一、左值和右值
左值:指表达式结束后依然存在的持久对象。
右值:表达式结束就不再存在的临时对象。
简单来说就是,左值相当于地址值,右值相当于数据值。
int i=42;
int &r=i; //正确,r引用i
int &&rr=i //错误,不能将一个右值引用绑定到一个左值上
int &r2=i*42; //错误,i*42是一个右值
const int &r3=i*42; //正确,我们可以将一个const的引用绑定到一个右值上
int &&r2=i*42; //正确,将rr2绑定到乘法结果上
右值引用和左值引用的区别:
- 左值引用不能绑定到要转换的表达式、字面常量或返回右值的表达式。右值引用恰好相反,可以绑定到这类表达式,但不能绑定到一个左值上。
- 右值引用必须绑定到右值的引用,通过
&&
获得。右值引用只能绑定到一个将要销毁的对象上,因此可以自由地移动其资源。
注意!变量是左值 :不能将一个右值引用绑定到一个变量上,即使这个变量是右值引用类型也不可以。
int &&rr1 =42; //正确,字面值常量是右值
int &&r2 =rr1; //错误,表达式rr1是左值!
二、标准库move函数
std::move 可以将一个左值强制转化为右值,继而可以通过右值引用使用该值,以用于移动语义。
int &&rr1 =42; //正确,字面值常量是右值
int &&rr3 =std::move(rr1); //OK
注意: 可以销毁一个移后源对象,也可以赋予它新值,但是不能使用一个移后源对象的值。