C++——左值与右值、右值引用、移动语义与完美转发
在C++或者C语言中,一个表达式(可以是字面量、变量、对象、函数的返回值等)根据其使用场景不同,分为左值表达式和右值表达式。
一、左值和右值的定义
-
左值的英文为
locator value
,简写为lvalue
,可意为存储在内存中、有明确存储地址(可寻址)的数据 -
右值的英文为
read value
,简写为rvalue
,指的是那些可以提供数据值的数据(不一定可寻址,例如存储与寄存器中的数据)
二、如何判断一个表达式是左值还是右值(大多数场景)
-
可位于赋值号(=)左侧的表达式就是左值;反之,只能位于赋值号右侧的表达式就是右值。例如:
int a = 5;
其中,变量a就是一个左值,而字面量5就是一个右值。
注:C++中的左值可以当作右值使用,反之则不行,如
int b = 10; //b是一个左值 a = b; //a、b都是左值,只不过b可以当作右值使用 10 = b; //错误,10是一个右值,不能当作左值使用
-
有名称的、可以获取到存储地址的表达式即为左值;反之则为右值
以上面定义的变量a、b为例,a和b是变量名,则通过&a和&b可以获得他们的存储地址,因此a和b都是左值;反之,字面量5、10,它们既没有名称,也无法获取其存储地址(字面量通常存储在寄存器中,或者和代码存储在一起),因此5、10都是右值
三、C++右值引用
C++ 98/03标准中就有引用,但这里的引用只能操作左值,无法对右值添加引用,故被称为左值引用,例如:
int num = 10;
int &b = num; //正确
int &c = 10; //错误
注意,虽然C++ 98/03标准不支持为右值建立非常量左值引用,但允许使用常量左值引用操作右值。即,