由右值引用引用的内存

Memory referenced by rvalue references

本文关键字:引用 内存      更新时间:2023-10-16

给定一个函数

int foo()
{
   return 15;
}

可以使用

int&& ref = foo();

但不能使用:

int& ref = foo();

这是可以理解的,因为foo()的返回值是一个rvalue。然而,我如何能够使用以下内容?

#include <iostream>
template<typename T>
void f(T&& param)
{
   param *= 2;
}
int foo()
{
   return 15;
}
int test1()
{
   int&& ref = foo();
   std::cout << "ref = " << ref << std::endl;
   f(ref);
   std::cout << "ref = " << ref << std::endl;
}
int main()
{
   test1();
   return 0;
}

,输出如下,看起来很合理:<>之前Ref = 15Ref = 30之前

似乎ref指向可写内存。行:

   int&& ref = foo();

ref分配可写内存?

这个标准是否兼容?

使用g++ 4.8.2对代码进行了测试。

是的,该行为是定义良好的,因为通过将返回值绑定到右值引用,您已经扩展了临时对象的生命周期,以匹配它所绑定的引用的生命周期。

源自§12.2 [class.temporary]

4

,在两种上下文中,临时变量在与完整表达式末尾不同的位置被销毁。...
5 ,第二个上下文是当引用绑定到临时对象时。引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:
...(例外列表,没有一个适用于这种情况)

注意,生存期扩展规则只适用于右值,而不适用于xvalues(参考§12.2/1)。因此,如果您的示例执行了以下操作,那么您将拥有一个悬空引用:

int&& ref = std::move(foo());