C++ Value Category
简介
值类别是 C++ 表达式具有的属性之一(还有其类型)。
C++ 最开始只有 左值与右值 的说法,且其含义随着时间变化和模糊,后来,为了支持 移动语义 ,C++11 引入了 右值引用 ,C++ 标准委员会重新设计了值类别,新的类别系统围绕 identity 和 movable 这个两个概念定义了核心值类别类型 lvalue 、xvalue 、prvalue ,以及复合值类别类型 glvalue 、rvalue ,再后来 C++17 为了消除 [Copy Elision 导致构造函数调用的不明确,围绕 glvalue 提供被初始化对象地址、prvalue 提供 initializer 重新明确了前面五种值。
- glvalue(generalized lvalue)
- an expression whose evaluation determines the identity of an object, bit-field, or function.
- rvalue
- a prvalue or an xvalue.
- lvalue
- a glvalue that is not an xvalue.
- xvalue(expiring value)
- a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime).
- prvalue(pure rvalue)
- an expression whose evaluation initializes an object or a bit-field, or computes the value of an operand of an operator, as specified by the context in which it appears, or an expression that has type cv void.
可以先预先说明,rvalue 是可移动的,可见,关键在于理解 identity 和 movable 的真实含义:
- identity
- 结合词义,identity 本质上就是区分值是否是同一对象的标识,而结合ANSI aliasing 规则 ,不难联想到这里的 identity 指的是存放值的一个“位置”,亦即内存地址或者寄存器。
- movable
- 这个值能够应用在移动构造函数、移动赋值函数、实现了移动语义的其他函数。
而此时,对于上面的五种值类别的分类的本质就一目了然了:
value category | identity of s.th. | movable |
---|---|---|
glvalue |
X | |
rvalue |
X | |
lvalue |
X | |
xvalue |
X | X |
prvalue |
X |
即 glvalue 是 identity of s.th. ,rvalue 是 movable ,xvalue 是两者交集,剩下的 lvalue 和 prvalue 是两者补集。
评价
这一切罪恶的根源,在于
=
表示复制 like 的语义,而不是符号重命名 like 的。
C++ 17
https://zhuanlan.zhihu.com/p/22821671?from_voters_page=true
If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object. [ Example: T x = T(T(T())); calls the T default constructor to initialize x. ]