基于循环等效范围

Range-based for loop equivalent

本文关键字:范围 循环 于循环      更新时间:2023-10-16

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

{
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。

这个答案依赖于这些信息,并说:

的范围尽可能快,因为它缓存了结束迭代器[引文],使用预增量,并且仅取消引用迭代器一次。

所以如果你倾向于写:

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

然后,是的,的范围可能会稍微快一点,因为它也更容易写下没有理由不使用它(在适当的时候)。

附言:我说过它尽可能快,但它并不比可能的如果您编写小心地手动循环。

我很好奇它现在是否真的有什么不同。在我看来,这只是句法上的糖。例如,在一个可以执行auto it = s.rbegin(); it != s.rend(); ++it的循环中,它需要返回反向迭代器的锅炉板代码,其中基于范围的For循环需要beginend。如果它所节省的只是打字,那么它还提供什么其他优势,因为它只期望beginend?我很好奇我上面引用的答案是否仍然有分量,因为这篇论文是2007年的。

正如@DyP所说,这一部分在最终标准中发生了一些变化。C++11 6.5.4基于范围的for语句[stmt.range]:

1对于形式的基于范围的for语句

for ( for-range-declaration : expression ) statement

范围init等价于用括号包围的表达式

( expression )

并且对于形式的基于范围的CCD_ 11语句

for ( for-range-declaration : braced-init-list ) statement

范围init等价于支持的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是表达式的类型,开始expr结束expr确定如下:

  • 如果_RangeT是数组类型,则开始expr结束expr分别为__range__range + __bound,其中__bound是数组绑定。如果_RangeT是未知大小的数组或不完整类型的数组,则程序格式错误;

  • 如果_RangeT是类类型,则在类_RangeT的作用域中查找非限定idbeginend,就像通过类成员访问查找一样(3.4.5),并且如果其中一个(或两个)找到至少一个声明,则开始expr结束expr分别为__range.begin()__range.end()

  • 否则,begin exprend expr分别为begin(__range)end(__range),其中beginend是通过参数相关查找(3.4.2)查找的。为了进行此名称查找,命名空间CCD_ 32是相关联的命名空间。

[示例:

int array[5] = { 1, 2, 3, 4, 5 };
for (int& x : array)
x *= 2;

--结束示例]

2在范围声明的decl说明符seq中,每个decl说明符应为类型说明符constexpr