问题描述
下面的逻辑让我很困惑。它编译正常,但 foo
的结果是一个右值。这是一个临时的。为什么我可以获取对容器中项目的非常量引用?
#include <array>
std::array<int,3> foo(){
return std::array<int,3>{0,1,2};
}
int main(){
for(int & item: foo())
item = 0;
}
解决方法
range based for loop 具有语法
attr(optional) for ( init-statement(optional)range_declaration : range_expression ) loop_statement
它扩展为
{
init-statement
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
如您所见,右值的生命周期延长了 __range
,因此将左值引用放入 __range
绑定到的集合中是有效的。循环结束后,__range
将超出范围,破坏已创建的右值对象。
这就是为什么即使您正在修改一个注定要被销毁的对象它也能工作。