C++标准给出了一系列规则,来规定哪些表达式有哪种值类别。我们可以结合上面给出的值类别定义去理解这些规则。举个例子,对于xvalue表达式,有这样的规则:
如果一个表达式是函数调用或重载运算符表达式,且其返回类型为右值引用,例如 std::move(x),那么这个表达式是xvalue表达式
对于这个规则,我们可以这么理解:首先,如果要返回一个对象,肯定是要在栈上面预留内存空间的,所以这个对象是有identity的。第二,返回类型是右值引用,所以它会让使用这个表达式的语句呈现移动语义,所以是可移动的。因此,这个表达式是xvalue表达式。
对于xvalue还有这样的规则
对象成员表达式,即"a.m",如果 a 是右值且 m 是非引用类型的非静态数据成员,则这个表达式是xvalue表达式
这条规则可以这么理解:首先,a是右值,也就是可以移动,那么作为a对象的一部分,m也应当是可以移动的。第二,访问对象的“.”运算符实际上是计算地址偏移,既然有地址,那么肯定是有identity的。因此,这个表达式是xvalue表达式。
再比如:
对象成员表达式,即"a.m",如果 m 是成员枚举符或非静态成员函数,则这个表达式是prvalue表达式










