在线文档教程
C++
语言 | Language

Range-based for loop

基于范围的循环%28自C++11%29

在范围上执行for循环。

用作更易读的,相当于传统的用于循环操作范围内的值,例如容器中的所有元素。

句法

attr(optional) for ( range_declaration : range_expression ) loop_statement

attr-any number of attributes
range_declaration-a declaration of a named variable, whose type is the type of the element of the sequence represented by range_expression, or a reference to that type. Often uses the auto specifier for automatic type deduction
range_expression-any expression that represents a suitable sequence (either an array or an object for which begin and end member functions or free functions are defined, see below) or a braced-init-list.
loop_statement-any statement, typically a compound statement, which is the body of the loop

range_declaration may be a structured binding declaration. for (auto&& first,second : mymap) { // use first and second }(since C++17)

解释

以上语法生成的代码相当于以下%28__range,,,__begin__end仅适用于%29:

{ auto && __range = range_expression ; for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }{ auto && __range = range_expression ; for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }(until C++17)
{ auto && __range = range_expression ; for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }
{ auto && __range = range_expression ; auto __begin = begin_expr ; auto __end = end_expr ; for ( ; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }{ auto && __range = range_expression ; auto __begin = begin_expr ; auto __end = end_expr ; for ( ; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }(since C++17)
{ auto && __range = range_expression ; auto __begin = begin_expr ; auto __end = end_expr ; for ( ; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }

范围[医]计算表达式以确定要迭代的序列或范围。顺序的每个元素依次被取消引用并分配给变量,并在范围内指定类型和名称。[医]申报。

begin_exprend_expr定义如下:

  • 中频范围[医]表达式是数组类型的表达式,则begin_expr__rangeend_expr(__range + __bound),在哪里__bound如果数组的大小未知或类型不完整,则程序的格式为%29。

  • 中频范围[医]表达式是类类型的表达式。C有一个名为begin和/或名为end%28无论该成员的类型或可访问性如何%29,则begin_expr__range.begin()end_expr__range.end()

  • 否则,begin_exprbegin(__range)end_exprend(__range),通过参数相关查找%28非ADL查找未执行%29。

中频范围[医]表达式返回一个临时表达式,它的生存期将被延长到循环的末尾,如绑定到rvalue引用所指示的那样。__range,但请注意,在范围内的任何临时生命周期。[医]表达不是延伸。

就像传统的循环一样,断续语句可以用于提前退出循环,并且继续语句可以用下一个元素重新启动循环。

ATTR表示可选的属性...

注记

如果初始化器%28范围[医]表达式%29是带括号的列表,[医][医]范围被推断为std::initializer_list<>&&

它是安全的,事实上,在泛型代码中,使用演绎来转发引用是更可取的,for (auto&& var : sequence)...

任何一个名为beginend,无论它是类型、数据成员、函数还是枚举数,无论其可访问性如何,都会导致__range.begin()__range.end()用作begin_exprend_expr分别。因此,基于范围的for循环不能用于包含成员类型或名为枚举数的类。beginend即使提供了适当的命名空间范围空闲函数。

而变量在范围内声明。[医]声明通常在循环中使用。[医]语句,不需要这样做。

在C++17中,开始表达式和结束表达式的类型不一定是相同的,事实上,结束表达式的类型不一定是迭代器:它只需要能够与之进行不平等的比较。这样就可以用谓词%28e.g分隔范围。“迭代器指向空字符”%29。

关键词

for...

二次

#include <iostream> #include <vector> int main() { std::vector<int> v = {0, 1, 2, 3, 4, 5}; for (const int& i : v) // access by const reference std::cout << i << ' '; std::cout << '\n'; for (auto i : v) // access by value, the type of i is int std::cout << i << ' '; std::cout << '\n'; for (auto&& i : v) // access by reference, the type of i is int& std::cout << i << ' '; std::cout << '\n'; for (int n : {0, 1, 2, 3, 4, 5}) // the initializer may be a braced-init-list std::cout << n << ' '; std::cout << '\n'; int a[] = {0, 1, 2, 3, 4, 5}; for (int n : a) // the initializer may be an array std::cout << n << ' '; std::cout << '\n'; for (int n : a) std::cout << 1 << ' '; // the loop variable need not be used std::cout << '\n'; }

二次

产出:

二次

0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 1 1 1 1 1 1

二次

另见

for_eachapplies a function to a range of elements (function template)

© cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

http://en.cppreference.com/w/cpp/language/range-for