【问题标题】:Why does a range-based for statement take the range by auto&&?为什么基于范围的 for 语句通过 auto&& 获取范围?
【发布时间】:2012-11-05 22:00:28
【问题描述】:

基于范围的for 语句在 §6.5.4 中定义为等同于:

{
  auto && __range = range-init;
  for ( auto __begin = begin-expr,
             __end = end-expr;
        __begin != __end;
        ++__begin ) {
    for-range-declaration = *__begin;
    statement
  }
}

其中range-init 定义为基于范围的for 的两种形式:

for ( for-range-declaration : expression )         =>   ( expression )
for ( for-range-declaration : braced-init-list )   =>   braced-init-list

(该子句进一步说明了其他子表达式的含义)

为什么__range 给定推导类型auto&&?我对auto&& 的理解是,它对于通过std::forward 传递表达式来保留表达式的原始值(左值/右值)很有用。但是,__range 不会通过std::forward 传递到任何地方。它仅在获取范围迭代器时使用,作为__range__range.begin()begin(__range) 之一。

使用“通用参考”auto&& 有什么好处? auto& 不够吗?

注意:据我所知,the proposal 没有说明选择 auto&&

【问题讨论】:

  • 这样你就可以使用范围内的右值了。
  • "据我所知,该提案没有说明 auto&& 的选择。" 而且该提案还使用了范围库,它没有存在于 C++11 中。
  • 为了将来参考,由 e.g. 描述的表达式的属性'lvalue' 或 'rvalue' 是它的值类别。

标签: c++ for-loop c++11 auto universal-reference


【解决方案1】:

auto& 不够用吗?

不,不会。它不允许使用计算范围的 r-value 表达式。使用auto&& 是因为它可以绑定到左值表达式右值表达式。因此,您无需将范围粘贴到变量中即可使其工作。

或者,换句话说,这是不可能的:

for(const auto &v : std::vector<int>{1, 43, 5, 2, 4})
{
}

const auto&amp; 不够吗?

不,不会。 const std::vector 只会将 const_iterators 返回到其内容。如果您想对内容进行非const 遍历,那将无济于事。

【讨论】:

  • 糟糕,我实际上是想问const auto&amp; 是否足够。这也不会绑定到任何东西吗?
  • @sftrabbit:它不会绑定到 non-const 左值。 const std::vector 只会返回 const 迭代器。
  • 谢谢。这意味着除了转发之外,auto&amp;&amp; 也可用于绑定到任何东西而不使其成为const
  • 澄清一下:for (const auto&amp; v : std::vector&lt;int&gt;{1, 43, 5, 2, 4}) {} 可以用于 const 遍历。
  • @fyzix:如果它不是临时向量怎么办?看,您不能根据范围是否为临时范围来更改基于范围的for 的定义。因此,无论您选择什么,const auto&amp;auto&amp;&amp; 在所有情况下都必须相同。如果您使用const auto&amp;,则您只能对所有范围进行const 迭代。如果你使用auto&amp;&amp;,你可以进行任何你想要的迭代。
猜你喜欢
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 2016-10-31
相关资源
最近更新 更多