在一个基于范围的for循环中,range-init的生命周期是多久?

25
在最新的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();
...

所以,在语句auto&& r = boo()结束时,boo()的临时返回值被销毁,然后r成为循环入口处的悬空引用。这个推理正确吗?如果不正确,为什么?

1
首先,vector<string> boo();并不是声明一个对象,而是声明一个函数。其次,我不理解你的问题。 - Nawaz
11
是的,“vector<string> boo()”是一个返回集合的示例函数的签名。然后在下一行调用该函数。 - Andrew Tomazos
2个回答

24
这个推理是正确的吗?如果不是,为什么?
直到这一点为止它是正确的:
因此,将临时返回值绑定到引用会将其生命周期延长到引用的生命周期。因此,该临时变量在整个循环中都存在(这也是为什么整个结构周围有额外的一组{}:为了正确限制该临时变量的生命周期)。
这是根据C ++标准§12.2的第5段所述的:
第二种情况是当引用被绑定到临时对象时。引用绑定或引用所绑定子对象的完整对象的临时对象除外,该临时对象的存留期与引用的存留期相同,但是:
[各种不适用于此处的异常]
这是一个有趣的属性,它允许滥用范围for循环进行非范围操作:http://ideone.com/QAXNf

9
推理不正确,因为boo按值返回临时对象。将这个临时对象绑定到引用意味着临时对象的生命周期被延长。标准引用(§12.2/5):

[…]引用所绑定的临时变量或作为引用所绑定的子对象的完整对象的临时变量的存活期与引用的存活期相同[…]

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接