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 关于此的博客也是一本很好的阅读材料.
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工作文件中.
你可以使用:
for (auto&& it : foo){
}
Run Code Online (Sandbox Code Playgroud)
auto &&
我更喜欢auto &
管理代理迭代器std::vector<bool>
.
在许多方面,这种混淆来自多年来成长的约定,以约束一个*
或一个&
类型而不是变量.
例如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)
这可能是最好的通用形式.