在以下示例中:
http://coliru.stacked-crooked.com/a/7a1df22bb73f6030
struct D{
int i;
auto test2(int&& j){
return [&](){ // captured by reference!
cout << i*(j);
};
}
};
int main()
{
D d{10};
{
auto fn = d.test2(10);
fn(); // 1. wrong result here
d.test2(10)(); // 2. but ok here
}
}
为什么d.test2(10)();
有效?
它应该真的有用,还是只是我的未定义行为等于正确的结果?
P.S。在阅读this之后,我只看到一个解释:在(2)临时生命周期延长到表达式结束时,调用发生在同一个表达式中&amp;&amp; crteation;而(1)实际上由2个表达式组成:
存在函数调用中的引用参数的临时绑定 直到包含该函数调用的完整表达式结束:if 该函数返回一个引用,该引用比完整表达式更长, 它变成了一个悬垂的参考。
是这样的吗?
答案 0 :(得分:4)
临时对象一直持续到创建它的行(井,完整表达式)的末尾,除非生命周期延长。
您的代码不会延长任何临时代码的生命周期。通过绑定到引用的生命周期扩展不会“通勤”,只有第一个绑定延长了生命周期。
所以第一个案例是UB,因为你有一个悬空参考。所提到的临时性消失在行的末尾:在下一行,你遵循引用,并且混乱hapens。
在第二种情况下,您的引用不会延长临时的生命周期,但临时持续时间比绑定它的引用更长!它们都在线的末端死亡,与构造的顺序相反。
所以这个电话有效。
答案 1 :(得分:-1)
它应该真的有用,还是只是我的未定义行为等于正确的结果?
似乎喜欢它。在您链接的示例中,您有以下警告:
warning: '<anonymous>' is used uninitialized in this function [-Wuninitialized]
未初始化的对象具有不确定的值,尝试访问这些值会导致未定义的行为。