值类别
Apr 9, 2017
如何把一个简单的事情搞复杂。
简单的开始
左值和右值是 C 和 C++ 语言中表达式值的一种分类。每个表达式都有类型和值类别。
如 1 + 1
的类型为 int
,值类别为右值。
在 C++ 03 左值和右值很容易区分。
左值(left value, lvalue)为内存地址,可以出现在赋值等号的左边和右边。
1 | int x; |
右值(right value, rvalue)为只能出现在赋值等号右边的表达式。
1 | int x; |
复杂的延续
C++ 11 引入了移动语义。
对于类型 T ,T&&
称为右值引用 (rvalue reference)。T&
称为左值引用(lvalue reference)。
如果类型 T 实现了移动构造函数,则称 T 为可移动的。
引入了移动语义,问题随之而来。
1 | int&& f() {...} |
那么 f()
是左值还是右值?
f()
不是左值因为左值不可移动。
f()
不是右值因为可以出现在赋值等号的左边。
所以引入一种新的值类别,称为亡值(eXpiring value, xvalue)。f()
为亡值。
原先的左值变成了泛左值(generalized value, glvalue)。
原先的右值变成了纯右值(pure value, prvalue)。
定义新的左值为非亡值的泛左值。
定义新的右值为纯右值或者亡值。
用图表示就是
1 |
|
表达式一定是左值,亡值,右值中的一种。
左值等具体代码可参考基础类别。
具体的定义可以参考n3055。