range-for 遍历一个range,对逐个元素做操作,比起之前的for循环,语法更简洁,可读性更高,同时引入range的概念大大提高适用范围。
语法
for ( range_declaration : range_expression )
loop_statement
- range_declaration
- 元素类型的命名变量声明,可以是原始类型,引用或auto声明
- range_expression
- 表示范围的表达式,可以是原生数组,容器对象,实现begin和end的自定义类型,或者是大括号的初始化列表
同时,break和continue还是一样的功能可以在循环中使用。
实现伪代码:
{
auto && __range = range_expression ;
for (auto __begin = begin_expr, __end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
关于range的说明:
支持原生数组
range支持原生数组,但是不支持new的动态数组
int ns[] = { 1, 2, 3, 4, 5 };
for ( auto n : ns )
{
std::cout << n << std::endl;
}
支持STL容器
std::vector<int> v{1,2,3,4};
for ( auto & n : v )
{
n *= n;
}
for (auto n : v)
{
std::cout << n << " ";
}
// 输出:1 4 9 16
支持自定义类型
class my_array
{
public:
my_array() : v_({ 1, 2, 3, 4 }) {}
using Iter = std::vector<int>::iterator;
Iter begin() { return v_.begin(); }
Iter end() { return v_.end(); }
private:
std::vector<int> v_;
};
// test
my_array ma;
for ( auto & n : ma )
{
std::cout << n << " ";
}
// 输出:1 2 3 4
注意:
- range_expression如果是临时对象也没有关系,生命期会延续到循环结束
- 可以使用引用类型
&
来减少range元素对象考虑 - 还可以用右值引用来接range_expression,
for(auto&& var : sequence)
,自动触发引用左值或右值的推断。