C++ Value Category

简介

值类别是 C++ 表达式具有的属性之一(还有其类型)。

C++ 最开始只有 左值与右值 的说法,且其含义随着时间变化和模糊,后来,为了支持 移动语义 ,C++11 引入了 右值引用 ,C++ 标准委员会重新设计了值类别,新的类别系统围绕 identitymovable 这个两个概念定义了核心值类别类型 lvaluexvalueprvalue ,以及复合值类别类型 glvaluervalue ,再后来 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 是可移动的,可见,关键在于理解 identitymovable 的真实含义:

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. ]

参考资料