右值引用转换后的地址变化

address changes after a rvalue reference conversion

#include <iostream>
using namespace std;

int main()
{
  int i = 0;
  cout << &i << endl;

  const auto &ref = (short&&)i;
  cout << &ref << endl;

  return 0;
}

为什么 &i&ref 不同? (short&)i 不会导致此问题。 (short&&)i 是否生成临时变量?

(short&&)i 创建一个临时对象,因此您使用其他对象的地址,因此地址可能不同。

显然它创建了一个临时文件。

实际上编译器会自己告诉你。 试试这个:

auto &ref = (short&&)i;
cout << &ref << endl;

错误说:

error: non-const lvalue reference to type 'short' cannot bind to a temporary of type 'short'

测试代码here.

这是因为你在进行不同类型的演员表。 C 风格的显式转换强制转换总是静态强制转换,如果它可以被解释为静态强制转换的话;否则它会重新解释演员表。 And/or 根据需要进行常量转换。

(short&&)i 是静态转换,因为它可以解释为 static_cast<short&&>(i)。它创建一个临时 short 对象,ref 绑定到该对象。作为一个不同的对象,它有不同的地址。

(short&)i 是一个重新解释的转换,因为它不能被解释为格式错误的 static_cast<short&>(i)。它将 int 引用重新解释为短引用,并且 ref 绑定到同一个对象。请注意,通过此引用访问对象将具有未定义的行为。

这将创建一个对存在的事物的左值引用:

const auto& ref = i;

表达式 &ref&i 因此会给出相同的结果。

这也适用于:

const auto& ref = (int&)i;

这基本上是一回事。

但是,转换为非左值引用的对象 T(因此,转换为一个值,或另一种类型的右值引用!)必须创建一个临时的;当绑定到 ref 时,这个临时文件会延长生命周期。但是现在 ref 不是 "refer to" i,所以 address-of 结果会不同。

It's actually a little more complicated than that,但你明白了。此外,不要写这样的代码! int 不是 short,你不能假装它是。