错误:types'int'的非常量引用的types'int'的右值的无效初始化

错误的forms:

int &z = 12; 

正确forms:

 int y; int &r = y; 

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

C ++ 03 3.10 / 1说:“每个expression式不是左值就是右值。 值得注意的是,左值与右值是expression式的属性,而不是对象的属性。

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

R值是临时的,在他们所生活的全部expression式(“分号”)的末尾蒸发。 例如, 1729x + ystd::string("meow")x++都是rvalues。

操作符的地址要求其“操作数应该是一个左值”。 如果我们可以取一个expression式的地址,则expression式是左值,否则是右值。

  &obj; // valid &12; //invalid 
 int &z = 12; 

在右边, inttypes的临时对象是从整型文字12创build的,但是临时的不能绑定到非const引用。 因此,错误。 它是一样的:

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

为什么临时创build? 因为引用必须引用内存中的对象,而对于存在的对象,则必须先创build它。 由于对象是未命名的,所以它是一个临时对象。 它没有名字。 从这个解释来看,为什么第二种情况是好的。

一个临时对象可以绑定到const引用,也就是说,你可以这样做:

 const int &z = 12; //ok 

C ++ 11和Rvalue参考:

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

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

请注意, && intead的& 。 还要注意的是,即使与z绑定的对象是一个由整型文字12创build的临时对象, const也不再需要。

由于C ++ 11引入了右值引用int&现在被称为左值引用

12是一个编译时常量,不能像int&引用的数据那样改变。 你可以做的是

 const int& z = 12; 

引用是“隐藏的指针”(非空)的东西可以改变(左值)。 你不能将它们定义为常量。 这应该是一个“可变”的事情。

编辑::

我在想

 int &x = y; 

几乎相当于

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

其中__px是一个新名称, __px #define x只在包含x引用声明的块内工作。

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

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

  • 由文字数字( 12 )组成的expression式是“右值”
  • 不允许用右值创build非const引用: int &ri = 12; 是不合格的
  • 允许用右值创build一个const引用:在这种情况下,编译器创build一个未命名的对象; 只要参考本身存在,这个对象就会一直存在。

你必须明白这些是C ++规则。 他们只是。

发明一种不同的语言很容易,比如说C ++,它的规则略有不同。 在C ++中,允许用右值创build一个非const引用。 这里没有什么不一致或不可能的。

但是,如果程序员可能得不到他想要的东西,C ++devise人员会正确地决定避免这种风险,这样会导致一些有风险的代码。