强制auto成为循环范围内的引用类型

P45*_*ent 22 c++ for-loop range auto c++11

假设我有foo一个人口稠密的std::vector<double>.

我需要对这个向量的元素进行操作.我有动力写作

for (auto it : foo){
   /*ToDo - Operate on 'it'*/
}
Run Code Online (Sandbox Code Playgroud)

但似乎这不会回写,foo因为它it是一个值类型:已经采用了向量元素的深层副本.

我可以提供一些指导auto来制作it参考类型吗?然后我可以直接操作it.

我怀疑我错过了一些简单的语法.

Nia*_*all 27

最小的auto参考

循环可以声明如下:

for (auto& it : foo) {
   //    ^ the additional & is needed
   /*ToDo - Operate on 'it'*/
}
Run Code Online (Sandbox Code Playgroud)

这将允许it作为对每个元素的引用foo.

关于这些循环的"规范形式"存在一些争论,但auto&在这种情况下应该做到这一点.

一般auto参考

在更一般的意义上(在容器的细节之外),以下循环起作用(并且可能是优选的).

for (auto&& it : container) {
   //    ^ && used here
}
Run Code Online (Sandbox Code Playgroud)

auto&&允许绑定左值和右值.当在通用或一般(例如模板情况)中使用时,该表格可以达到期望的平衡(即,引用,副本,prvalue/xvalue返回(例如代理对象)等).

赞成将军auto&&,但如果您必须具体说明表格,请使用更具体的变体(例如auto,auto const&等等).

为什么auto&&更好?

正如在此处的其他答案和评论中所述.为什么auto&&更好?只要它会做什么,你认为它应该在大多数情况下,看到这个建议其更新.

与往常一样,Scott Meyers 关于此的博客也是一本很好的阅读材料.

  • @YogiBear:例如在`std :: vector <bool>`中管理代理 (2认同)
  • 对于那些想知道为什么'auto &&`更可取的人,我强烈建议阅读Scott Meyers关于Universal References的文章:http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers基本上,`auto && `必要时会变成'auto &`,但也允许`auto &&`的r值优化 (2认同)

Tem*_*Rex 20

我会用auto&&:

for (auto&& it : foo) {
    // bla
}
Run Code Online (Sandbox Code Playgroud)

原因在N3994 " 基于范围的For-Loops:下一代(修订版1) "中有详细说明,它可以更好地处理代理对象(例如来自的代理对象std::vector<bool>).

事实上,C++ 1z的建议(已经由-std=c++1z模式中的Clang 3.5 SVN支持)提出了语法:

// c++1z only
for (it : foo) { 
    // bla
}
Run Code Online (Sandbox Code Playgroud)

作为一个简写for (auto&& it : foo).

更新:N3994提案未被投票到 C++ 17工作文件中.


Jar*_*d42 5

你可以使用:

for (auto&& it : foo){

}
Run Code Online (Sandbox Code Playgroud)

auto &&我更喜欢auto &管理代理迭代器std::vector<bool>.


Bat*_*eba 5

在许多方面,这种混淆来自多年来成长的约定,以约束一个*或一个&类型而不是变量.

例如int* a是真的int *a; ie a是指向type类型的指针int.

这同样适用于引用:在这种情况下int& a,a是对类型值的引用int.

所以你真正想做的是写,for (auto &it : foo)所以it是对推断类型的引用auto.然后,您可以使用it操作底层矢量元素.这通常会写成

for (auto& it : foo)

继续前进,您可能想要使用r值引用:for (auto&& it : foo)这可能是最好的通用形式.