📅  最后修改于: 2023-12-03 14:58:07.371000             🧑  作者: Mango
在 C++ 中,每个表达式都可以分为一种“值类别”(value category):lvalue、prvalue 和 xvalue。了解这些值类别对于理解 C++ 的语言特性和实现机制非常重要。
lvalue 表示“左值”。在 C++ 的最初版本中,所有的变量都是左值,即可以出现在赋值语句的左边。例如:
int a = 1; // 'a' 是一个左值
a = 2; // 'a' 是一个左值
但随着 C++ 发展,一些语言特性(比如 C++11 中的移动语义)需要引入新的值类别。这使得 lvalue 的定义发生了变化:现在,lvalue 表示“可以取地址的表达式”。也就是说,它必须代表某个具体的对象或函数,而不是常量或计算结果。例如:
int a = 1; // 'a' 是一个 lvalue
int b = a; // 'a' 是一个 lvalue,'b' 是一个 prvalue
prvalue 表示“纯右值”(pure rvalue)。它是在表达式求值之后产生的不可变的值。比如:
int a = 1; // 'a' 是一个 lvalue
int b = a+2; // 'a+2' 是一个 prvalue,'b' 是一个 lvalue
在 C++ 11 中,prvalue 值类别被分为两种:纯右值 (PRvalue) 和 xvalue。
xvalue 表示“可扩展右值引用”。它是 C++11 中新增的值类别之一。xvalue 既可以被认为是右值,也可以被认为是左值。它表示“可以被移动的、即将销毁的值”。比如:
class A {
public:
A(A&& rhs) { /* 移动构造函数 */ };
A& operator=(A&& rhs) { /* 移动赋值函数 */ };
};
A foo(); // 返回一个 A 对象的右值
int main() {
A a = foo(); // 'foo()' 是一个 prvalue,'a' 是一个 xvalue
A&& b = foo(); // 'foo()' 是一个 prvalue,'b' 是一个 xvalue 引用
return 0;
}
在 C++11 中,我们可以通过 std::move 将一个左值转化为 xvalue:
int a = 1;
int&& b = std::move(a); // 'a' 是一个左值,'b' 是一个 xvalue 引用