(传统的,先前的c ++ 11 lvalue-)引用如何在C++中工作

Man*_*d3r 1 c++ rvalue lvalue c++11

指针很简单.有一些存储器保存一个地址.要获取(有意义的)取消引用值,将返回地址指向的内存所包含的值.

引用在某种程度上类似于它们:它们保持与临时对象的"链接".但是当我分配或使用引用时会发生什么?

#include <iostream>
using namespace std;
int one(){
    return 1;
}
int main()
{
    const int &rone = one();
    cout << &rone << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么这样做?这个地址是临时对象的地址吗?

sh-4.2# g++ -std=c++11 -o main *.cpp
sh-4.2# main
0x7fff9d2a4e74
Run Code Online (Sandbox Code Playgroud)

这个地址指向哪里?如果它指向神奇的临时对象,为什么我不能做以下事情.(我很清楚它是一个右值,&只接受左值,但为什么?)

int main()
{
    cout << &one() << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题超出了c ++的编程方面.它更多地是在技术方面,C++如何在内部工作.主要是我试图理解移动语义的上下文中的右值引用,这需要理解那些传统的引用(我几乎没用过).

M.M*_*M.M 6

另一种思考参考的方法是别名.绑定引用为对象提供另一个名称.在C++ 11之前,这两个片段完全相同:

int a = 5;
int &b = a;
Run Code Online (Sandbox Code Playgroud)

int b = 5;
int &a = b;
Run Code Online (Sandbox Code Playgroud)

此后,a并且b是同一对象两个名字.(C++ 11引入了一种不对称性,其中decltype包括返回类型中的引用).

在你的第一个例子中没有任何不同.绑定rone为临时对象的名称,语言规则说这会使临时对象的生命周期也被扩展.

在您的第二个示例中,没有引用.尽管运算符address-of具有相同的拼写,但它仍然是用于声明引用的符号的不同语言元素.这是非法的,因为语言定义表明地址运算符不能应用于创建临时对象的表达式.