假设我foo
填充了std::vector<double>
。
我需要操作此向量的元素。我有动力去写
for (auto it : foo){
/*ToDo - Operate on 'it'*/
}
但似乎这不会回写foo
,因为it
是值类型:已经采用了向量元素的深层副本。
我可以为auto
提供一些指导,使it
成为引用类型吗?然后我可以直接在it
上操作。
我怀疑我错过了一些简单的语法。
答案 0 :(得分:26)
最小auto
参考
循环可以声明如下:
for (auto& it : foo) {
// ^ the additional & is needed
/*ToDo - Operate on 'it'*/
}
这将允许it
成为foo
中每个元素的引用。
关于这些循环的“规范形式”存在一些争论,但auto&
应该在这种情况下起作用。
常规auto
参考
在更一般的意义上(在容器的细节之外),以下循环起作用(并且可能更好)。
for (auto&& it : container) {
// ^ && used here
}
auto&&
允许绑定左值和右值。当在通用或一般(例如模板情况)中使用时,该表格可能达到期望的平衡(即引用,副本,prvalue / xvalue返回(例如代理对象)等)。
支持常规auto&&
,但如果您必须具体说明表单,请使用更具体的变体(例如auto
,auto const&
等。)
为什么auto&&
更好?
正如此处的其他答案和评论中所述。为什么auto&&
更好?在大多数情况下,只需执行您认为应该执行的操作,请参阅this proposal和its update。
与往常一样,Scott Meyers关于此事的blog也是一个很好的阅读。
答案 1 :(得分:20)
我会使用auto&&
:
for (auto&& it : foo) {
// bla
}
原因在N3994“基于范围的For-Loops:下一代(修订版1)”中详细说明,它可以更好地与代理对象一起使用(例如来自std::vector<bool>
的那些)。
事实上,C ++ 1z的提议(在-std=c++1z
模式下已经由Clang 3.5 SVN支持)提出了语法:
// c++1z only
for (it : foo) {
// bla
}
作为for (auto&& it : foo)
的缩写。
更新:N3994提案是not voted into C ++ 17工作文件。
答案 2 :(得分:5)
您可以使用:
for (auto&& it : foo){
}
auto &&
首选auto &
来管理代理迭代器和std::vector<bool>
。
答案 3 :(得分:5)
在很多方面,这种混淆来自于多年来成长的惯例,即将*
或&
绑定到类型而不是变量。
例如int* a
确实是int *a
;即a
是指向int
类型值的指针。
同样适用于引用:对于int& a
,a
是对int
类型值的引用。
所以你真正想做的是写for (auto &it : foo)
,所以it
是对auto
推断出的类型的引用。然后,您可以使用it
来操作底层矢量元素。通常情况下,这将被写为
for (auto& it : foo)
继续前进,您可能希望使用 r值参考:for (auto&& it : foo)
,这可能是最佳的一般形式。