C ++ 11:基于范围的语句:“range-init”生命周期?
在最新的C ++标准中暗示:
for (foo : bar) baz;
等同于:
{ auto && r = bar; for ( auto it = r.begin(), end = r.end(); it != end; ++it ) { foo = *it; baz; } }
当上面的bar是一个函数调用返回一个集合,例如:
vector<string> boo();
即
for (auto bo : boo()) ...
不行:
auto&& r = boo(); ...
因此,boo()的临时返回值在声明“auto && r = boo()”的末尾被销毁,然后r是循环入口处的挂起引用。 ?? 这个推理是否正确? 如果没有,为什么不呢?
这个推理是否正确? 如果没有,为什么不呢?
这是正确的,直到这一点:
因此,boo()的临时返回值在声明“auto && r = boo()”的末尾被销毁[…]
绑定一个临时引用将其生命周期延长为引用。 因此,整个循环的临时持续时间(这也是为什么在整个构造周围有一个额外的集合:正确地限制该临时的生命周期)。
这是根据C ++标准的§12.2的第5段:
第二个上下文是引用绑定到临时的时候。 引用所绑定的临时对象或引用所绑定的子对象的完整对象的临时对象在引用的生命周期内一直存在,除非:
[在这里不适用的各种例外]
这是一个有趣的属性,允许滥用ranged-for循环的非范围的东西: http ://ideone.com/QAXNf
推理是不正确的,因为boo
按值返回一个临时对象。 将此临时对象绑定到引用意味着临时对象的生命周期被延长。 标准报价(§12.2 / 5):
[…]引用所绑定的临时对象或引用所绑定的子对象的完整对象的临时对象,
如果boo
返回一个参考,推理是正确的。 一个expression式返回一个临时引用的例子是string("a") += string("b")
; 在基于范围的for
循环中使用此值会导致未定义的行为。