什么决定了临时工的生命周期何时扩展到const引用或rvalue引用?

Cla*_*diu 3 c++ reference lifetime rvalue-reference c++11

鉴于:

struct hurg { ... };

hurg get_hurg() { return hurg(); }
hurg&& get_mhurg() { return hurg(); }
Run Code Online (Sandbox Code Playgroud)

我的理解和实验表明,以下不是未定义的行为(编辑:感谢答案,结果我错了,get_mhurg()示例未定义的行为):

{
    const hurg& a = get_hurg(); 
    hurg&& b = get_hurg();
    const hurg& c = get_mhurg(); 
    hurg&& d = get_mhurg();
    // do stuff with a, b, c, d
}
// a, b, c, d are now destructed
Run Code Online (Sandbox Code Playgroud)

也就是说,临时的寿命hurg对象返回通过get_hurg()get_mhurg()延伸直至范围的端部.

但是,在(函数从这里)的情况下:

template <typename T>
auto id(T&& x) -> decltype(auto) { return decltype(x)(x); }    
Run Code Online (Sandbox Code Playgroud)

使用它像:

{
    const hurg& x = id(hurg()); 
    // the hurg() 'x' refers to is already destructed

    hurg&& y = id(hurg());
    // the hurg() 'y' refers to is already destructed

    // undefined behavior: use 'x' and 'y'
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,的寿命hurg延长.

是什么决定了临时工作时间的延长?并且,特别是,何时将函数的结果绑定到const lvalue ref或rvalue ref是安全的?

更具体地说,id案件究竟发生了什么?

Bar*_*rry 6

来自[class.temporary]:

有两种情况,临时表演在不同于完整表达结束时被摧毁.第一个上下文是调用默认构造函数来初始化数组的元素[...]

第二个上下文是引用绑定到临时的.绑定引用的临时值或作为绑定引用的子对象的完整对象的临时值在引用的生存期内持续存在,除了:
(5.1) - 绑定到引用中的引用参数的临时对象函数调用(5.2.2)一直持续到包含调用的完整表达式完成.
(5.2) - 函数返回语句(6.6.3)中返回值的临时绑定的生存期不会延长 ; 临时在return语句中的full-expression结束时被销毁.
(5.3) - 临时绑定到new-initializer中的引用(5.3.4)一直持续到包含new-initializerfull-expression完成 .

所以有两件事.首先,get_mhurg是未定义的行为.您返回的临时生命周期不会延长.其次,临时传递id持续到包含函数调用的完整表达式结束,但没有进一步.与此同时get_mhurg,临时不是通过扩展.所以这也是未定义的行为.