给定:
struct hurg { ... };
hurg get_hurg() { return hurg(); }
hurg&& get_mhurg() { return hurg(); }
我的理解和实验表明以下内容不是未定义行为(编辑:感谢答案,结果证明我错了,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
也就是说,由get_hurg()
和get_mhurg()
返回的暂时对象hurg
的生命周期会一直延续到作用域的结束。
但在此示例中(来自这里的函数):
template <typename T>
auto id(T&& x) -> decltype(auto) { return decltype(x)(x); }
使用方法如下:
{
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'
}
在这种情况下,
hurg
的生命周期不会被延长。一般来说,什么决定了临时对象的生命周期何时被延长?特别地,在何时将函数的结果绑定到const lvalue引用或rvalue引用是安全的?
更具体地说,在
id
案例中究竟发生了什么?