标准的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
上创建一个临时对象并绑定到fooRef
的{{1}}参数。 foo
在fooRef
行被销毁。所以我认为临时应该在这里销毁,因为生命延长不是传递性的。
问题:
#0
是什么意思?这是until the function exits
吗?
为什么我会得到untill it finished executing
输出。第5
行还有临时对象吗?
如何解释标准引用以弄清楚此示例的工作原理?
非常感谢参考标准的逐步原子演练。谢谢!
P上。 S.一个接受的答案here也告诉代码是#2
我不明白,为什么我得到这样的程序输出。
答案 0 :(得分:3)
直到函数退出是什么意思?这是否意味着直到它完成执行?
是
为什么我得到5输出。第2行上是否还存在临时对象?
取消引用未绑定到活动对象的引用是未定义的行为,因此您可以获得5
以及42
以及其他任何内容(包括崩溃)。对于具有未定义行为的程序,您根本无法期待。
如何解释标准引用以弄清楚此示例的工作原理?
非常像你已经做过的那样。临时绑定到函数参数fooRef
,它从函数返回时被销毁。由于该临时值与返回值绑定,因此该函数返回时该对象不再存在。稍后,您将取消引用悬空引用,它会为您提供UB。
答案 1 :(得分:1)
这意味着直到结束括号,即}
。
你调用了UB,你有一个悬空引用。
尝试对代码进行以下修改并查看其打印内容。它可能会打印6
因为这是堆栈中的最后一个。或者尝试传递一个std::string
,你可能会崩溃。
int main (void)
{
const int& numberRef = foo(5);
foo(6);
std::cout << numberRef;
return 0;
}