为什么基于范围的for语句通过auto &&获取范围?

Jos*_*eld 15 c++ for-loop auto c++11 universal-reference

基于范围的for声明在§6.5.4定义为等同于:

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

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

for ( for-range-declaration : expression )         =>   ( expression )
for ( for-range-declaration : braced-init-list )   =>   braced-init-list
Run Code Online (Sandbox Code Playgroud)

(该条款进一步规定了其他子表达式的含义)

为什么__range给出推导类型auto&&?我的理解auto&&是,通过传递它来保留表达式的原始值(左值/右值)是有用的std::forward.但是,__range不会通过任何地方std::forward.它得到的范围内时迭代器作为一个人的只用__range,__range.begin()begin(__range).

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

注意:据我所知,该提案没有说明选择auto&&.

Nic*_*las 20

不会自动就足够了吗?

不,它不会.它不允许使用计算范围的r值表达式.auto&&之所以使用是因为它可以绑定到l值表达式 r值表达式.因此,您不需要将范围粘贴到变量中以使其工作.

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

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

const auto&不够吗?

不,它不会.A const std::vector只会返回const_iterator其内容.如果你想对const内容进行非遍历,那将无济于事.

  • 只是为了澄清:`for(const auto&v:std :: vector <int> {1,43,5,2,4}){}`可用于const遍历. (6认同)
  • @fyzix:如果它*不是*一个临时向量怎么办?看,您不能根据范围是否是临时范围来更改基于范围的 `for` 的定义。所以无论你选择什么,`const auto&amp;` 或 `auto&amp;&amp;` 在所有情况下都必须相同。如果你使用 `const auto&amp;`,你只能对所有范围进行 `const` 迭代。如果你使用`auto&amp;&amp;`,你可以有任何你想要的迭代。 (2认同)
  • @starriet:所讨论的“auto&amp;&amp;”是由基于范围的“for”机制构建的。如果基于范围的“for”*内部*使用“auto&amp;”,您发布的代码将无法编译。它使用“auto&amp;&amp;”来*允许*该代码进行编译。这就是我回答的重点。 (2认同)