C++ 11:基于范围的for语句:"range-init"生命周期?

And*_*zos 19 c++ c++11

在最新的C++标准中,它意味着:

for (foo : bar)
    baz;
Run Code Online (Sandbox Code Playgroud)

等同于:

{
    auto && r = bar;
    for ( auto it = r.begin(), end = r.end(); it != end; ++it )
    {
        foo = *it;
        baz;
    }
}
Run Code Online (Sandbox Code Playgroud)

当上面的bar是一个返回集合的函数调用时,例如:

vector<string> boo();
Run Code Online (Sandbox Code Playgroud)

for (auto bo : boo())
    ...
Run Code Online (Sandbox Code Playgroud)

这条线不会成为:

auto&& r = boo();
...
Run Code Online (Sandbox Code Playgroud)

因此boo()的临时返回值在语句"auto && r = boo()"的末尾被销毁,然后r是循环入口处的挂起引用.?? 这个推理是否正确?如果没有,为什么不呢?

R. *_*des 19

这个推理是否正确?如果没有,为什么不呢?

到目前为止这是正确的:

因此boo()的临时返回值在语句"auto && r = boo()"[...]结束时被销毁.

将临时绑定到引用会将其生命周期延长为引用的生命周期.所以临时持续整个循环(这也是为什么{}在整个构造周围有一个额外的集合:正确地限制该临时的生命周期).

这是根据C++标准§12.2的第5段:

第二个上下文是引用绑定到临时的.绑定引用的临时对象或绑定引用的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:

[此处不适用的各种例外]

这是一个有趣的属性,允许滥用非范围事物的ranged-for循环:http://ideone.com/QAXNf


Phi*_*ipp 7

推理不正确,因为boo按值返回临时对象.将此临时对象绑定到引用意味着临时对象的生命周期被扩展.标准报价(§12.2/ 5):

[...]引用绑定的临时值或作为引用绑定的子对象的完整对象的临时值在引用的生命周期内仍然存在[...]

如果boo返回引用,推理将是正确的.返回对临时引用的表达式的示例是string("a") += string("b"); 在基于范围的for循环中使用此值会导致未定义的行为.