暂时延长使用寿命

Temporary lifetime extension

本文关键字:时延      更新时间:2023-10-16

标准的第12.2.5节说:

在函数调用中临时绑定到引用参数 (5.2.2(一直持续到包含叫。在函数返回中临时绑定到返回值语句 (6.6.3( 一直保留到函数退出。在所有这些事例,在表达式求值期间创建的临时初始化引用,但临时引用除外引用是绑定的,在完整表达式的末尾被销毁它们的创建顺序与完成顺序相反他们的建设。

我正在尝试理解以下代码:

#include <iostream>
const int& foo(const int& fooRef)
{
    return fooRef;
}                                        // #0
int main (void)
{
    const int& numberRef = foo(5);     // #1
    std::cout << numberRef;            // #2
    return 0;
}

在线#1创建一个临时对象并将其绑定到 fooReffooRef在第 #0 行被销毁。我认为临时应该在这里销毁,因为寿命延长不是传递的。

问题:

  1. until the function exits是什么意思?这是否意味着untill it finished executing

  2. 为什么我会得到5输出。临时对象是否仍然存在于第 #2 行?

  3. 如何解释标准报价以弄清楚此示例的工作原理?

参考

该标准的分步原子演练将不胜感激。谢谢!

附言这里接受的答案还告诉代码是broken的,我不明白,为什么我得到这样的程序输出。

函数退出之前是什么意思?这是否意味着直到它完成执行?

是的。

为什么我会得到 5 输出。临时对象是否仍然存在于第 #2 行?

取消引用未

绑定到活动对象的引用是未定义的行为,因此您可能会获得5以及42以及其他任何内容(包括崩溃(。您根本无法对具有未定义行为的程序有任何期望。

如何解释标准报价以弄清楚此示例的工作原理?

就像你已经做过的那样。临时参数绑定到函数参数 fooRef ,从函数返回时被销毁。由于该临时对象绑定到返回值,因此当函数返回时,该对象将不复存在。稍后,您将取消引用一个悬空引用,这将为您提供 UB。

  1. 这意味着直到右大括号,即 } .

  2. 您调用了 UB,您有一个悬而未决的引用。

尝试对代码进行以下修改,看看它打印的内容。它可能会打印6因为这是堆栈上的最后一个。或者尝试传递std::string,您可能会崩溃。

int main (void)
{
    const int& numberRef = foo(5);  
    foo(6);
    std::cout << numberRef;
    return 0;
}