为什么int&r = 0是非法的,而const int&r = 0是合法的?

Why int& r = 0 is illegal while const int& r = 0 is legal?

本文关键字:int const 非法 为什么      更新时间:2023-10-16

我是C++的新手。我正在努力学习const的概念。有人能告诉我为什么第一种说法是非法的,而第二种说法是合法的吗?

int i = -1, &r = 0;         
const int i = -1, &r = 0;  

i在这里只是转移注意力,问题是int &r = 0;const int &r = 0;

非常量左值引用必须直接绑定到左值。0不是左值,因此int &r = 0;失败。

常量左值引用可以绑定到右值。当这种情况发生时,它不会直接绑定。相反,会创建一个临时的(此处为const int类型),并从右值进行复制初始化。由于这种约束,临时的使用寿命得以延长。

因此const int &r = 0;是合法的,并且具有与const int __temp = 0; const int &r = __temp; 类似的效果

int i = -1, &r = 0;与相同

int i = -1;
int &r = 0; 

这里的问题是你不能写int &r = 0;,因为引用的初始化需要初始化器是一个左值(一个地址为你可以接受),而字面上的0不是。

但是const引用的初始值设定项不需要是左值,所以const int &r = 0;是可以的。

i = -1,位创建了一个初始化为-1i变量,但对后面的引用没有影响,所以让我们关注:

int &r = 0;      // illegal
const int &r = 0;

const int&版本所做的是延长其绑定值的生存期:换句话说,0值保留下来,以便通过r使用,直到定义r的范围结束。

很容易指出,同样的慷慨并没有扩展到int&版本,"因为它不是一个左值"为什么这个更有趣的问题在C++常见问题解答:中进行了讨论

在C++中,非常量引用可以绑定到左值,常量引用可以链接到左值或右值,但没有任何东西可以绑定到非常量右值。这是为了保护人们不改变临时物品的价值,这些物品在新价值被使用之前就被销毁了。例如:

void incr(int& a) { ++a; }
int i = 0;
incr(i);    // i becomes 1
incr(0);    // error: 0 is not an lvalue

如果允许incr(0),那么没有人看到的一些临时值将增加,或者更糟的是,0的值将变为1。后者听起来很傻,但实际上在早期的Fortran编译器中存在这样一个错误,即留出一个内存位置来保存值0。

int i = -1, &r = 0;基本上等同于写入

int i = -1;
int &r = 0

第二个语句试图将非const的左值绑定到0,后者根本不是左值(0不是一个可以获取地址的对象)。然而,当它是一个const左值时,它会成功,因为它被绑定(但不是直接绑定)到右值。