当前位置: 首页 > 知识库问答 >
问题:

基于范围的循环:通过值或对常量的引用获取项?

袁志专
2023-03-14

阅读一些基于范围的循环示例,他们提出了两种主要方法1、2、3、4

std::vector<MyClass> vec;

for (auto &x : vec)
{
  // x is a reference to an item of vec
  // We can change vec's items by changing x 
}

for (auto x : vec)
{
  // Value of x is copied from an item of vec
  // We can not change vec's items by changing x
}

当我们不需要更改vec项目时,IMO的示例建议使用第二个版本(按值)。为什么他们不建议const引用的内容(至少我没有找到任何直接的建议):

for (auto const &x : vec) // <-- see const keyword
{
  // x is a reference to an const item of vec
  // We can not change vec's items by changing x 
}

不是更好吗?当它是一个常量时,它不是在每次迭代中都避免了一个冗余副本吗?


共有3个答案

子车煌
2023-03-14

当我们不需要更改vec项时,示例建议使用第一个版本。

然后他们给出了一个错误的建议。

为什么他们不建议一些恒定的参考

因为他们给出了一个错误的建议:-)你所说的是正确的。如果您只想观察对象,则无需创建副本,也无需对其进行非const引用。

编辑:

我看到您链接的引用都提供了迭代一系列int值或一些其他基本数据类型的示例。在这种情况下,由于复制int并不昂贵,因此创建一个副本基本上等同于(如果不是比)具有一个观察常量

但是,对于用户定义的类型,通常情况下并非如此。UDT的复制成本可能很高,如果您没有创建副本的理由(例如在不更改原始对象的情况下修改检索到的对象),则最好使用常量

满雨石
2023-03-14

如果你有一个std::vector

for (auto x : vec)
    ....

但是如果你有一个d::向量

for (const auto & x : vec)
    ....

燕禄
2023-03-14

如果您不想更改项目,也不想复制,那么auto-const

for (auto const &x : vec)

谁建议你使用自动

以下是回顾:

  • 选择自动x,当你想要工作的副本。
  • 选择自动

 类似资料:
  • C 11引入了基于ranged的for循环,该循环在内部使用(const)迭代器实现,因此: 基本上相当于更详细(是的,可以使用简化): 然而,通常需要一个项目的索引。第二种方法很简单: 在基于范围的中,它不是那么简单。但我想知道这是否是一个可以完全避免迭代器的便携解决方案: (版本将是相同的,但需要注意不要将非容器与const引用混合,这可能并不总是显而易见的。) 显然,这依赖于几个假设: >

  • C 11 使用基于范围的for循环对作为类成员的std::向量进行迭代的代码是什么?我尝试了以下几个版本:

  • 在临时范围上基于范围的for循环中,Barry提到以下内容不受被破坏的临时对象的影响,我测试的成员v确实存在于for循环的整个循环中(因为在for循环的整个循环中没有调用析构函数X)。解释是什么?

  • 由于valgrind中出现了一些分段错误和警告,我发现这段代码不正确,并且在for range循环中有一些悬而未决的引用。 看起来好像开始和结束是从一个临时循环中提取的,并且在循环中丢失了。 当然,一种方法是 然而,我想知道为什么for(auto e:f()[5])是一个错误,以及是否有更好的方法或某种方法来设计f,甚至容器(

  • 我对C很陌生,现在就在做中学习。在课堂材料中,我有以下功能: 几分钟前,我像这样使用了普通for循环:

  • 有一组好的规则来确定是按值传递还是常量引用 如果函数打算将参数更改为副作用,则通过non-const引用。 如果函数不修改它的参数,并且参数是基元类型,则按值取它。 否则通过const引用获取它,除非在以下情况下:如果函数需要复制const引用,则按值获取它。 对于以下构造函数,如何确定它?