基于范围的循环等效

时间:2013-12-24 09:15:10

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

因此,根据n2243,基于范围的for循环等同于:

{
     auto && __range = ( expression );

     for ( auto __begin = std::Range<_RangeT>::begin(__range),
                  __end = std::Range<_RangeT>::end(__range);
          __begin != __end;
          ++__begin )
     {
         for-range-declaration = *__begin;
         statement
     }    
}

然后说2 If the header <iterator_concept> is not included prior to a use of the range-based for statement, the program is ill-formed.所以我质疑这是最新的。我也很好奇std::Range是什么,或者它纯粹是一个实现细节。我能找到的最近的是n3350

answer依赖于此信息并说:

  

范围尽可能快,因为它缓存结束   iterator [引用],使用预增量,只解引用   迭代器一次。

     

所以,如果你倾向于写:

     

for(iterator i = cont.begin(); i != cont.end(); i++) { /**/ }

     

然后,是的,range-for可能稍快一点,因为它也更容易   写下没有理由不使用它(适当时)。

     

P.S。我说它尽可能快,但速度并不快   可能。如果你写的话,你可以达到完全相同的性能   手动循环。

我很好奇现在是否真的有所作为。据我所知,它只是语法糖。例如,在你可以执行auto it = s.rbegin(); it != s.rend(); ++it的循环中,它需要返回反向迭代器的样板代码,其中基于范围的for循环需要beginend。如果所有节省的都是打字,那么它还提供了哪些其他优势,因为期望beginend?我很好奇,如果上面引用的答案仍然很重要,因为该论文是从2007年开始的。

1 个答案:

答案 0 :(得分:3)

正如@DyP所说,这部分在最终标准中有所改变。 C ++ 11 6.5.4基于范围的for语句[stmt.ranged]:

  

1对于表单

的基于范围的for语句
  for ( for-range-declaration : expression ) statement
     

range-init 等同于括号所包围的表达式

  ( expression )
     

以及表单

的基于范围的for语句
  for ( for-range-declaration : braced-init-list ) statement
     

range-init 等同于 braced-init-list 。在每种情况下,基于范围的for语句等同于

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

其中__range__begin__end是仅为展示定义的变量,_RangeT是表达式的类型, begin-expr < / em>和 end-expr 确定如下:

     
      
  • 如果_RangeT是数组类型,则 begin-expr end-expr __range__range + __bound分别是__bound是数组绑定的地方。如果_RangeT是未知大小的数组或不完整类型的数组,则该程序格式不正确;

  •   
  • 如果_RangeT是类类型,则会在类{{1}的范围内查找 unqualified-ids beginend好像通过类成员访问查找(3.4.5),如果其中任何一个(或两者)找到至少一个声明, begin-expr    end-expr 分别为_RangeT__range.begin();

  •   
  • 否则, begin-expr end-expr 分别为__range.end()begin(__range),其中end(__range)并且使用参数依赖查找查找begin(3.4.2)。出于此名称查找的目的,   namespace end是一个关联的命名空间。

  •   
     

[例如:

std
     

-end example]

     

2在 for-range-declaration decl-specifier-seq 中,每个 decl-specifier 应为 >类型说明符 int array[5] = { 1, 2, 3, 4, 5 }; for (int& x : array) x *= 2;