错误的形式:
int &z = 12;
正确的表格:
int y;
int &r = y;
的问题 的:
为什么第一个代码错了?标题中错误的“含义”是什么?
答案 0 :(得分:117)
C ++ 03 3.10 / 1说:“每个表达式都是左值或左值。”重要的是要记住左值与右值是表达式的属性,而不是对象的属性。
Lvalues命名超出单个表达式的对象。例如,obj
,*ptr
,ptr[index]
和++x
都是左值。
Rvalues是在他们生活的完整表达结束时蒸发的临时值(“以分号”表示)。例如,1729
,x + y
,std::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中,你可以这样写:
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)
这些是C ++语言的规则:
12
)组成的表达式是“rvalue”int &ri = 12;
格式错误您必须了解这些是C ++规则。他们就是。
很容易发明一种不同的语言,比如C ++',规则略有不同。在C ++中,允许使用rvalue创建非const引用。这里没有任何不一致或不可能。
但它会允许程序员可能达不到他想要的一些有风险的代码,并且C ++设计者正确地决定避免这种风险。
答案 4 :(得分:0)
引用是可以改变(lvalues)的东西的“隐藏指针”(非空)。您无法将它们定义为常量。它应该是一个“变量”的东西。
EDIT ::
我在考虑
int &x = y;
几乎相当于
int* __px = &y;
#define x (*__px)
其中__px
是新名称,而#define x
仅在包含x
引用声明的块内。