错误:从'int'类型的右值初始化'int&'类型的非const引用无效

时间:2011-11-28 08:51:10

标签: c++ pointers reference

错误的形式:

int &z = 12;

正确的表格:

int y;
int &r = y;

问题 的:
为什么第一个代码错了?标题中错误的“含义”是什么?

5 个答案:

答案 0 :(得分:117)

C ++ 03 3.10 / 1说:“每个表达式都是左值或左值。”重要的是要记住左值与右值是表达式的属性,而不是对象的属性。

Lvalues命名超出单个表达式的对象。例如,obj*ptrptr[index]++x都是左值。

Rvalues是在他们生活的完整表达结束时蒸发的临时值(“以分号”表示)。例如,1729x + ystd::string("meow")x++都是右值。

地址运算符要求其“操作数应为左值”。如果我们可以获取一个表达式的地址,则表达式是左值,否则它是一个右值。

 &obj; //  valid
 &12;  //invalid

答案 1 :(得分:43)

int &z = 12;

在右侧,从整数文字int创建12类型的临时对象,但临时对象不能绑定到非const引用。因此错误。它与:

相同
int &z = int(12); //still same error

为什么会创建一个临时的?因为引用必须引用内存中的对象,并且对于存在的对象,必须首先创建它。由于对象未命名,因此它是临时对象。它没有名字。从这个解释来看,为什么第二种情况没问题就变得非常清楚了。

临时对象可以绑定到const引用,这意味着,您可以这样做:

const int &z = 12; //ok

C ++ 11和Rvalue Reference:

为了完整起见,我想补充一点,C ++ 11引入了rvalue-reference,它可以绑定到临时对象。所以在C ++ 11中,你可以这样写:

int && z = 12; //C+11 only 

请注意&&&个整数。另请注意,即使const绑定到的对象是由整数文字z创建的临时对象,也不再需要12

由于C ++ 11引入了 rvalue-reference int&现在称为 lvalue-reference

答案 2 :(得分:8)

12是一个编译时常量,与int&引用的数据不同,它不能更改。您可以做的是

const int& z = 12;

答案 3 :(得分:4)

非const和const引用绑定遵循不同的规则

这些是C ++语言的规则:

  • 由文字编号(12)组成的表达式是“rvalue”
  • 不允许使用右值创建非const引用:int &ri = 12;格式错误
  • 允许使用rvalue创建一个const引用:在这种情况下,编译器会创建一个未命名的对象;只要引用本身存在,该对象就会持久存在。

您必须了解这些是C ++规则。他们就是。

很容易发明一种不同的语言,比如C ++',规则略有不同。在C ++中,允许使用rvalue创建非const引用。这里没有任何不一致或不可能。

但它会允许程序员可能达不到他想要的一些有风险的代码,并且C ++设计者正确地决定避免这种风险。

答案 4 :(得分:0)

引用是可以改变(lvalues)的东西的“隐藏指针”(非空)。您无法将它们定义为常量。它应该是一个“变量”的东西。

EDIT ::

我在考虑

int &x = y;

几乎相当于

int* __px = &y;
#define x (*__px)

其中__px是新名称,而#define x仅在包含x引用声明的块内。