猿问
下载APP

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

读取基于范围环的一些例子他们建议两种主要方式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 

}

不是更好吗?它是不是避免了每次迭代中的冗余副本,而它是一个const?


慕莱坞森
浏览 63回答 3
3回答

繁星coding

如果您不想更改项目以及想要避免复制,那么这auto const &是正确的选择:for (auto const &x : vec)建议你使用的人auto &是错的。别管他们。这是概述:选择auto x何时使用副本。选择auto &x何时使用原始项目并可以修改它们。选择auto const &x何时使用原始项目,不会修改它们。

互换的青春

如果你有一个std::vector<int>或std::vector<double>,那么它可以使用auto(带有值复制)而不是const auto&,因为复制一个int或一个double便宜:for (auto x : vec)&nbsp; &nbsp; ....但是如果你有一个std::vector<MyClass>,哪里MyClass有一些非平凡的复制语义(例如std::string,一些复杂的自定义类等),那么我建议使用const auto&以避免深拷贝:for (const auto & x : vec)&nbsp; &nbsp; ....

HUWWW

当我们不需要更改vec项目时,示例建议使用第一个版本。然后他们给出了错误的建议。为什么他们不建议const引用的东西因为他们给出了错误的建议:-)你提到的是正确的。如果您只想观察一个对象,则无需创建副本,也不需要对其进行非const引用。编辑:我看到你链接的引用都提供了迭代一系列int值或一些其他基本数据类型的示例。在这种情况下,由于复制int并不昂贵,因此创建副本基本上等同于(如果不是更有效)进行观察const &。但是,对于用户定义的类型,通常不是这种情况。复制UDT可能很昂贵,如果您没有理由创建副本(例如修改检索到的对象而不更改原始副本),则最好使用a const &。
打开App,查看更多内容
随时随地看视频慕课网APP
我要回答