c++ - 什么决定临时对象的生命周期何时扩展到 const 引用或右值引用?

标签 c++ c++11 reference rvalue-reference lifetime

给定:

struct hurg { ... };

hurg get_hurg() { return hurg(); }
hurg&& get_mhurg() { return hurg(); }

我的理解and experimenting表明以下是不是未定义的行为(编辑:感谢答案,事实证明我错了,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 对象的生命周期被延长到结束范围。

但是,在(来自 here 的函数)的情况下:

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 的生命周期不会延长。

什么决定了临时对象的生命周期一般何时延长?而且,特别是,什么时候将函数的结果绑定(bind)到 const 左值引用或右值引用是安全的?

更具体地说,id 案例中到底发生了什么?

最佳答案

来自 [class.temporary]:

There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression. The first context is when a default constructor is called to initialize an element of an array [...]

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a sub-object to which the reference is bound persists for the lifetime of the reference except:
(5.1) — A temporary object bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
(5.2) — The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
(5.3) — A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer.

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

关于c++ - 什么决定临时对象的生命周期何时扩展到 const 引用或右值引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31796511/

相关文章:

c++ - stringstream:为什么这段代码不返回 4?

c++ - 调用x64汇编函数后C++变量重置为0

c++ - 如何检测不连续的矩形

c++ - 我可以从基于范围的 for 中 move 元素吗?

c++ - 如何区分使用内存池分配的类

多维数组的 PHP 自定义数据类型

c# - MVC 编译错误,在临时 ASP.NET 文件中使用 WebApplication1

c++ - windows是如何用c++创建的?

c++ - 如何处理函数签名中间的参数包?

c++ - 理解常量