我认为部分混淆是由于使用auto
,虽然不是强制性的,但很常见。基本上,基于范围的 forfor (type var : range)
意味着:迭代元素以range
创建var
使用. 这个结构在标准规定的常规 for 循环方面具有直接翻译:type
range
// for (for-range-declaration : range-init)
// statement
{
auto && __range = range-init;
for ( auto __begin = begin-expr, __end = end-expr;
__begin != __end; ++__begin ) {
for-range-declaration = *__begin;
statement
}
}
range-init和for-range-declaration可以是任何可以在扩展版本上替换并编译的东西。对于 for-range-declaration中的类型没有要求,它甚至可以与range-init所持有的不同:
// Convoluted example:
void printFloor(std::vector<double> const & v) {
for (int i : v) {
std::cout << ' ' << i;
}
}
因为可以使用允许扩展编译的任何类型auto
,所以它具有与在任何其他上下文中完全相同的语义,并且行为与在所有其他情况下完全相同。
将基于范围的 for 的要求更改为仅允许通过引用进行迭代会不必要地使语言(标准措辞)和实现复杂化(编译器不能只是扩展,因为for-range-declaration不仅仅是一个声明,而是一个限制使用值的形式),实际上限制了在需要值时需要更复杂的用户代码的结构的使用(用户必须手动复制)。请记住,这个结构只是为了简化代码,它不是一个启用功能,没有它就不能用这个结构做任何事情(你总是可以手动生成上面的扩展)。