右值引用(rvalue reference)是 C++11 为了实现移动语意(move semantic)和完美转发(perfect forwarding)而提出来的。
一、左值和右值
传统的C++引用(即左值引用)使得标识符关联到左值。
左值:一个表示数据的表达式,如变量名或解除引用的指针,程序可获取其地址。
C++11新增了右值引用,使用&&表示。
右值:即可出现在赋值表达式的右边,但是不能对其应用地址运算符的值。
区分左值和右值的便捷方法:
看能不能对表达式取地址,如果能,则为左值,否则为右值。
二、左值引用和右值引用
左值引用:即C++98里的引用,
举例:
int a = 10;
int& refA = a; // refA是a的别名, 修改refA就是修改a, a是左值,左移是左值引用
int& b = 1; //编译错误! 1是右值,不能够使用左值引用
这里int& refA = a;
编译器发现是左值引用,
会自动做如下转换:
int& refA -> int* const refA = &a;若需要refA = 20;
则编译器会自动转换成:
*refA = 20;
refA和a就共同操纵同一块地址了。
左值引用的本质是一个指针常量。
右值引用使用的符号是&&,
如:
inline double f(double tf) {return 5.0*(tf-32.0)/9.0};
using namespace std;
int main()
{
double tc = 21.5;
double&& rd1 = 7.07;
double&& rd2 = 1.8*tc + 32.0;
double&& rd3 = f(rd2);
cout<<"tc value and address:"<<tc<<","<<&tc<<endl;
cout<<"rd1 value and address:"<<rd1<<","<<&rd1<<endl;
cout<<"rd2 value and address:"<<rd2<<","<<&rd2<<endl;
cout<<"rd3 value and address:"<<rd3<<","<<&rd3<<endl;
cin.get();
return 0;
}
结果:
注意:这里rd1的类型是右值引用类型(double &&
),但是如果从左值和右值的角度区分它,它实际上是个左值。因为可以对它取地址,而且它还有名字,是一个已经命名的右值。