错误:types'int'的非常量引用的types'int'的右值的无效初始化
错误的forms:
int &z = 12;
正确forms:
int y; int &r = y;
问题 :
为什么第一个代码是错的? 标题中错误的“ 含义 ”是什么?
C ++ 03 3.10 / 1说:“每个expression式不是左值就是右值。 值得注意的是,左值与右值是expression式的属性,而不是对象的属性。
左值名称超出单个expression式的对象。 例如, obj
, *ptr
, ptr[index]
和++x
都是左值。
R值是临时的,在他们所生活的全部expression式(“分号”)的末尾蒸发。 例如, 1729
, x + y
, std::string("meow")
和x++
都是rvalues。
操作符的地址要求其“操作数应该是一个左值”。 如果我们可以取一个expression式的地址,则expression式是左值,否则是右值。
&obj; // valid &12; //invalid
int &z = 12;
在右边, int
types的临时对象是从整型文字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人员会正确地决定避免这种风险,这样会导致一些有风险的代码。