因此,根据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循环需要begin
和end
。如果所有节省的都是打字,那么它还提供了哪些其他优势,因为仅期望begin
和end
?我很好奇,如果上面引用的答案仍然很重要,因为该论文是从2007年开始的。
答案 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-idsbegin
和end
好像通过类成员访问查找(3.4.5),如果其中任何一个(或两者)找到至少一个声明, begin-expr end-expr 分别为_RangeT
和__range.begin()
;否则, begin-expr 和 end-expr 分别为
__range.end()
和begin(__range)
,其中end(__range)
并且使用参数依赖查找查找begin
(3.4.2)。出于此名称查找的目的, namespaceend
是一个关联的命名空间。[例如:
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;
。