当xvalue绑定到const左值引用时,它是否会延长xvalue的生命周期?

时间:2012-02-27 15:47:22

标签: c++ g++ c++11 rvalue-reference xvalue

如果我写下面的代码:

#include <iostream>

using namespace std;

int main()
{
  cout << &(int &&)123 << endl;
  return 0;
}

然后g++抱怨:

foo.cc: In function ‘int main()’:
foo.cc:7:20: error: taking address of xvalue (rvalue reference)

好的,感谢What are rvalues, lvalues, xvalues, glvalues, and prvalues?我得到了一个xvalue意味着它即将“过期”,这是有道理的。但现在如果我这样做:

#include <iostream>

using namespace std;

int main()
{
  const int &x = (int &&)123;
  cout << &x << endl;
  return 0;
}

这“工作”很好,会打印一个地址。所以,我有几个问题:

  1. 如果该值即将到期,为什么我可以参考它?引用不会使原始对象保持活动状态(对吗?)。
  2. 这样的引用会导致未定义的行为吗?例如。因为我们引用了一个可能已被破坏的对象?
  3. 通常有一种方法可以知道右值参考的生命周期吗?

2 个答案:

答案 0 :(得分:9)

也许我一个人但我认为这不安全:

const int &x = (int &&)123;

仅当通过直接引用临时对象的表达式初始化引用时,才会应用生命周期延长规则。换句话说,表达式必须带有“临时”属性。如果省略(int&&),那么对于绑定到引用,编译器将隐式创建一个prvalue表达式,该表达式引用一个临时对象,该对象由值123初始化,然后生命周期延长适用。

但是如果你在它们之间混合rvalue引用,编译器就无法知道编译时是否延长了引用对象的生命周期。

int a = 0;
const int &x = ((rand() == 42) ? (int&&)123 : (int&&)a);

因此我认为您的代码具有未定义的行为,因为您评估了悬空引用(即使仅用于获取其地址)。

答案 1 :(得分:3)

第12.2条第4-5段表示在第二个例子中延长了 的生命周期

  

有两种情况下,临时表在与完整表达结束时不同的点被销毁。 ...

     

第二个上下文是引用绑定到临时的。引用绑定的临时值或作为绑定引用的子对象的完整对象的临时值在引用的生存期内持续存在,除了:
  (这里没有例外情况)