【问题标题】:What determines when the lifetimes of temporaries get extended into const references or rvalue references?什么决定了临时对象的生命周期何时扩展到 const 引用或 rvalue 引用?
【发布时间】:2015-08-03 20:50:08
【问题描述】:

给定:

struct hurg { ... };

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

我对@9​​87654321@ 的理解表明以下是不是未定义的行为(编辑:感谢答案,事实证明我错了,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 的生命周期没有延长。

一般来说,什么决定了临时对象的生命周期何时延长?并且,特别是,何时将函数的结果绑定到 const lvalue ref 或 rvalue ref 是安全的?

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

【问题讨论】:

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


    【解决方案1】:

    来自 [class.temporary]:

    在两种情况下,临时对象在与完整表达式结尾不同的点被销毁。 第一个上下文是调用默认构造函数来初始化数组元素时 [...]

    第二个上下文是引用绑定到临时的。引用的临时对象 绑定或作为引用所绑定的子对象的完整对象的临时对象仍然存在 在引用的生命周期内,除了:
    (5.1) — 在函数调用 (5.2.2) 中绑定到引用参数的临时对象一直持续到完成 包含调用的完整表达式
    (5.2) — 在函数返回语句 (6.6.3) 中临时绑定到返回值的生命周期不是 扩展;临时在 return 语句中的 full-expression 末尾被销毁。
    (5.3) — 临时绑定到 new-initializer (5.3.4) 中的引用,直到完成 full-expression 包含 new-initializer

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

    【讨论】:

      【解决方案2】:

      我的理解和实验表明以下不是 未定义的行为:

      嗯,你的理解和实验是错误的。明智的提示 - 不要尝试未定义的行为。例如,您的实验可能会随机发生表明它是明确定义的行为,这是未定义行为的可能结果之一。

      使用get_mhurg() 的返回值是未定义的行为。您正在访问创建范围之外的临时 hurg()

      id 的情况只是表明延长寿命是愚蠢的。

      具体来说,生命周期延长仅适用于。它从不适用于任何类型的引用。您必须使用值初始化引用。 id 不返回值,因此不应用生命周期延长。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-14
        • 1970-01-01
        • 2012-11-15
        • 1970-01-01
        相关资源
        最近更新 更多