C++值类别概述
现代C++中,引入了左值右值的概念,用于区分不同类型的表达式和值,而后又进一步的引入了将亡值和纯右值的概念,左值和将亡值统称为泛左值;纯右值和将亡值统称为右值。关系如图所示
传统意义上的赋值操作符左侧的为左值,右侧的为右值,在C++11后,这是错误的概念。为更好的区分如上所述的四种值类别,本文将抛砖引玉,欢迎大家评论区指正。
左值
左值是具有变量名的表达式,它具有持久的内存地址,可以被取地址、引用和修改。
其通常用于表示具体的对象或变量,在 C++ 中最常见的表达式类型之一。
// x 是左值,具有变量名
int x = 10;
//value是右值引用,但value本身为左值,具有变量名,可以取地址
int&& value =5;
**注:**函数形参总是左值。
将亡值
将亡值是一种即将要被销毁的值,但仍然可以被引用的右值。将亡值通常发生在对象即将离开作用域、被移动(move)或转换为另一个类型时。它可以被引用,并且仍然处于可移动状态 。
// getString()的返回值是将亡值
std::string&& str = std::move(getString());
纯右值
纯右值是指无法被引用的右值,如字面量、临时对象的返回值等表示一个值没有对象的值。它们通常是临时的、一次性的值,只能用于计算,无法取地址。
纯右值通常用于表示临时的、无法被引用的值,例如函数返回值、表达式的计算结果等,语句执行完毕即被销毁。
int x = 10; // x 是左值,10是纯右值
int y = 20; // y 是左值,20是纯右值
int z = x + y; // x + y 是纯右值
纯右值和将亡值都属于右值,可以是不具名的临时变量,可以是即将离开作用域或被move的类型。左值和将亡值都属于泛左值。
总结
《Effective Modern C++》指出若能取得该表达式的地址,那么该表达式基本可以断定是左值。如果不能取得表达式的地址,则其通常为右值。对左值施加std::move作用时,其具有左值的特征,也能够绑定到右值引用,这类属于将亡值。区分、理解它们有助于编写更加高效、安全的代码。