C++11 基于范围的循环:按值获取项目或引用 const

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15176104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:06:30  来源:igfitidea点击:

C++11 range based loop: get item by value or reference to const

c++c++11

提问by masoud

Reading some examples of range based loops they suggest two main ways1, 2, 3, 4

阅读基于范围的循环的一些示例,他们提出了两种主要方式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 
}

or

或者

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

Well.

好。

When we don't need changing vecitems, IMO, Examples suggest to use second version (by value). Why they don't suggest something which constreferences (At least I have not found any direct suggestion):

当我们不需要更改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 
}

Isn't it better? Doesn't it avoid a redundant copy in each iteration while it's a const?

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

回答by Nawaz

If you don't want to change the items as well as want to avoidmaking copies, then auto const &is the correct choice:

如果您不想更改的项目,以及要避免复印,然后auto const &是正确的选择:

for (auto const &x : vec)

Whoever suggests you to use auto &is wrong. Ignore them.

谁建议你使用auto &是错误的。别理他们。

Here is recap:

这是回顾:

  • Choose auto xwhen you want to work with copies.
  • Choose auto &xwhen you want to work with original items and may modify them.
  • Choose auto const &xwhen you want to work with original items and will not modify them.
  • 选择auto x何时使用副本。
  • 选择auto &x何时使用原始项目并可以修改它们。
  • 选择auto const &x何时使用原始项目并且不修改它们。

回答by Mr.C64

If you have a std::vector<int>or std::vector<double>, then it's just fine to use auto(with value copy) instead of const auto&, since copying an intor a doubleis cheap:

如果您有std::vector<int>or std::vector<double>,那么使用auto(带值复制)代替 就可以了const auto&,因为复制 anint或 adouble很便宜:

for (auto x : vec)
    ....

But if you have a std::vector<MyClass>, where MyClasshas some non-trivial copy semantics (e.g. std::string, some complex custom class, etc.) then I'd suggest using const auto&to avoid deep-copies:

但是如果你有一个std::vector<MyClass>, whereMyClass有一些非平凡的复制语义(例如std::string,一些复杂的自定义类等),那么我建议使用const auto&以避免深层复制

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

回答by Andy Prowl

When we don't need changing vecitems, Examples suggest to use first version.

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

Then they give a wrong suggestion.

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

Why they don't suggest something which const references

为什么他们不建议 const 引用的东西

Because they give a wrong suggestion :-) What you mention is correct. If you only want to observean object, there is no need to create a copy, and there is no need to have a non-constreference to it.

因为他们给出了错误的建议 :-) 你提到的是正确的。如果只想观察一个对象,就没有必要创建副本,也没有必要对它进行非const引用。

EDIT:

编辑:

I see the references you link all provide examples of iterating over a range of intvalues or some other fundamental data type. In that case, since copying an intis not expensive, creating a copy is basically equivalent to (if not more efficient than) having an observing const &.

我看到您链接的所有参考资料都提供了在一系列int值或其他一些基本数据类型上进行迭代的示例。在这种情况下,由于复制 anint并不昂贵,因此创建副本基本上等同于(如果不是更有效)拥有一个观察const &

This is, however, not the case in general for user-defined types. UDTs may be expensive to copy, and if you do not have a reason for creating a copy (such as modifying the retrieved object without altering the original one), then it is preferable to use a const &.

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

回答by Benjamin Lindley

I'm going to be contrary here and say there is no need for auto const &in a range based for loop. Tell me if you think the following function is silly (not in its purpose, but in the way it is written):

我将在这里相反,说不需要auto const &基于范围的 for 循环。告诉我您是否认为以下函数很傻(不是它的目的,而是它的编写方式):

long long SafePop(std::vector<uint32_t>& v)
{
    auto const& cv = v;
    long long n = -1;
    if (!cv.empty())
    {
        n = cv.back();
        v.pop_back();
    }
    return n;
}

Here, the author has created a const reference to vto use for all operations which do not modify v. This is silly, in my opinion, and the same argument can be made for using auto const &as the variable in a range based for loop instead of just auto &.

在这里,作者创建了一个 const 引用,v用于所有不修改 v 的操作。在我看来,这很愚蠢,并且可以auto const &在基于范围的 for 循环中用作变量而不是仅仅使用相同的参数auto &.