1.左值和右值
首先,左值和右值是表达式的属性。C++中的表达式,不是左值就是右值。左值可以位于赋值语句的左侧,而右值则不能;可以做一个简单的归纳:当一个对象被用作右值的时候,用的是对象的值;当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。需要右值的地方可以用左值代替,但不能把右值当成左值使用。
介绍完左值右值,接下来介绍左值引用和右值引用。
2.左值引用
左值引用就是我们平常使用的“引用”。引用是为对象起的别名,必须被初始化,与变量绑定到一起,且将一直绑定在一起。
我们通过 & 来获得左值引用,可以把引用绑定到一个左值上,而不能绑定到要求转换的表达式、字面常量或是返回右值的表达式。举个例子:
int i = 42;
int &r = i; //正确,左值引用
int &r1 = i * 42; //错误, i*42是一个右值
const int &r2 = i * 42; //正确,可以将一个const的引用绑定到一个右值上
3.右值引用
右值引用就是必须绑定到右值的引用,他有着与左值引用完全相反的绑定特性,我们通过 && 来获得右值引用。右值有一个重要的性质——只能绑定到一个将要销毁的对象上。举个例子:
int &&rr = i; //错误,i是一个变量,变量都是左值
int &&rr1 = i *42; //正确,i*42是一个右值
4.其他区别
左值拥有持久的状态,而右值要么是字面常量,要么是在表达式求职过程中创建的临时对象。
右值引用的对象将要被销毁。不能将一个右值引用绑定到一个右值引用类型的变量上,因为变量都是左值。举个例子:
int &&rr1 = 42; //正确,42是右值
int &&rr2 = rr1; //错误,rr1是左值!
但是我们可以显示的将一个左值转换成对应的右值引用类型。通过move函数来执行。
int &&rr3 = std::move(rr1);