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_expr
和end_expr
定义如下:
- 中频范围[医]表达式是数组类型的表达式,则
begin_expr
是__range
和end_expr
是(__range + __bound)
,在哪里__bound
如果数组的大小未知或类型不完整,则程序的格式为%29。
- 中频范围[医]表达式是类类型的表达式。
C
有一个名为begin
和/或名为end
%28无论该成员的类型或可访问性如何%29,则begin_expr
是__range.begin()
和end_expr
是__range.end()
;
- 否则,
begin_expr
是begin(__range)
和end_expr
是end(__range)
,通过参数相关查找%28非ADL查找未执行%29。
中频范围[医]表达式返回一个临时表达式,它的生存期将被延长到循环的末尾,如绑定到rvalue引用所指示的那样。__range
,但请注意,在范围内的任何临时生命周期。[医]表达不是
延伸。
就像传统的循环一样,断续语句可以用于提前退出循环,并且继续语句可以用下一个元素重新启动循环。
ATTR表示可选的属性...
注记
如果初始化器%28范围[医]表达式%29是带括号的列表,[医][医]范围被推断为std::initializer_list<>&&
它是安全的,事实上,在泛型代码中,使用演绎来转发引用是更可取的,for (auto&& var : sequence)
...
任何一个名为begin
或end
,无论它是类型、数据成员、函数还是枚举数,无论其可访问性如何,都会导致__range.begin()
和__range.end()
用作begin_expr
和end_expr
分别。因此,基于范围的for循环不能用于包含成员类型或名为枚举数的类。begin
或end
即使提供了适当的命名空间范围空闲函数。
而变量在范围内声明。[医]声明通常在循环中使用。[医]语句,不需要这样做。
在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_each | applies a function to a range of elements (function template) |
---|
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。