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

注意:

  1. range_expression如果是临时对象也没有关系,生命期会延续到循环结束
  2. 可以使用引用类型&来减少range元素对象考虑
  3. 还可以用右值引用来接range_expression,for(auto&& var : sequence),自动触发引用左值或右值的推断。

参考