一、左值和右值
1、什么是左值,什么是右值?
左值指的是可以出现在赋值运算符(=)左侧的内容,但其实左值一般具有左值属性和右值属性,不仅可以出现在等号左侧,也可以出现在等号右侧。
右值指的是只能出现在赋值运算符(=)右侧,不能被赋值的内容。右值只具有右值属性。
左值实际上可以代表一个地址,而右值不是。
int i = 10;
i = i + 1;
上面代码中,i就是一个左值,它在第一条语句中位于等号的左侧,而10这个数值实际上就是右值,在等号右侧,并且它没有地址的概念。
二、左值引用和右值引用
1、左值引用
一般我们所使用的引用都是左值引用,可简称为引用。引用实际上就是变量的别名,下面是左值引用的简单使用例子:
int a = 5;
int& b = a;
b = 10; // b = 10, a = 10
上面的例子中,b是a的引用,并且b可以改变a的值,最终a=10。
2、什么是右值引用
右值引用是C++11新加入的概念,它是对右值的一种引用,下面是简单使用例子:
int&& rightValue = 3;
rightValue = 5;
上面代码中,rightValue是一个右值引用,它引用了3的数值,第二条语句它将rightValue的值改成了5。
3、一些特殊的例子
①前置递增递减运算符,如++i, --i,它们是左值表达式。例如:++i是直接给i变量加1,然后返回i本身,因为i是变量,所以可以被赋值,因此是左值表达式。
int i = 5;
(++i) = 10; // i = 20
②后置递增递减运算符,如i++,i--,它们是右值表达式。例如:i++是先产生一个临时变量来保存i的值,再给i加1,接着返回临时变量,之后系统再释放这个临时变量。
int i = 1;
int&& r1 = i++; // 可以,成功绑定到右值
int& r2 = i++; // 不可以,左值引用不能绑定到右值表达式
三、std::move函数
std::move函数是C++11中的新函数,它的作用是将一个左值强制转换成右值,带来的结果就是一个右值引用可以绑定到转换成的右值了。下面举个简单使用的例子:
void func(int&& arg){}
int i = 10;
int&& ri = std::move(i);
func(ri); // 不可以,std::move(i)返回的是右值,但ri本身是左值
func(std::move(i)); // 可以,因为std::move(i)是右值