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

时间:2014-08-06 11:17:54

标签: c++ c++11 for-loop range auto

假设我foo填充了std::vector<double>

我需要操作此向量的元素。我有动力去写

for (auto it : foo){
   /*ToDo - Operate on 'it'*/
}

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

我可以为auto提供一些指导,使it成为引用类型吗?然后我可以直接在it上操作。

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

4 个答案:

答案 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&&,但如果您必须具体说明表单,请使用更具体的变体(例如autoauto const&等。)

为什么auto&&更好?

正如此处的其他答案和评论中所述。为什么auto&&更好?在大多数情况下,只需执行您认为应该执行的操作,请参阅this proposalits 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& aa是对int类型值的引用。

所以你真正想做的是写for (auto &it : foo),所以it是对auto推断出的类型的引用。然后,您可以使用it来操作底层矢量元素。通常情况下,这将被写为

for (auto& it : foo)

继续前进,您可能希望使用 r值参考for (auto&& it : foo),这可能是最佳的一般形式。