跳到主要内容

C++值类别概述

现代C++中,引入了左值右值的概念,用于区分不同类型的表达式和值,而后又进一步的引入了将亡值和纯右值的概念,左值和将亡值统称为泛左值;纯右值和将亡值统称为右值。关系如图所示

Image

传统意义上的赋值操作符左侧的为左值,右侧的为右值,在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作用时,其具有左值的特征,也能够绑定到右值引用,这类属于将亡值。区分、理解它们有助于编写更加高效、安全的代码。