左值右值是表达式的属性,该属性称为 value category。按该属性分类,每一个表达式属于下列之一:
|
lvalue |
left value,传统意义上的左值 |
|
xvalue |
expiring value, x值,指通过“右值引用”产生的对象 |
|
prvalue |
pure rvalue,纯右值,传统意义上的右值(?) |
而 xvalue 和其他两个类型分别复合,构成:
|
lvalue + xvalue = glvalue |
general lvalue,泛左值 |
|
xvalue + prvalue = rvalue |
右值 |
++x 与 x++ 假定x的定义为 int x=0;,那么前者是 lvalue,后者是rvalue。前者修改自身值,并返回自身;后者先创建一个临时对像,为其赋值,而后修改x的值,最后返回临时对像。区分表达式的左右值属性有一个简便方法:若可对表达式用 & 符取址,则为左值,否则为右值。比如
|
&obj , &*ptr , &ptr[index] , &++x |
有效 |
|
&1729 , &(x + y) , &std::string("meow"), &x++ |
无效 |
对于函数调用,根绝返回值类型不同,可以是lvalue、xvalue、prvalue:
-
The result of calling a function whose return type is an lvalue reference is an lvalue
-
The result of calling a function whose return type is an rvalue reference is an xvalue.
-
The result of calling a function whose return type is not a reference is a prvalue.
2.const vs non-const
左值和右值表达式都可以是const或non-const。比如,变量和函数的定义为:
1 string one("lvalue"); 2 const string two("clvalue"); 3 string three() { return "rvalue"; } 4 const string four() { return "crvalue"; }