左值、右值、右值引用与move()、forward()

1、左值(lvalue):可以进行取地址(&)运算的是左值。或者有时候可以理解为 既能够出现在等号左边也能出现在等号右边的变量(或表达式)。

2、右值(rvalue):不可以进行取地址(&)运算的是右值。或者有时候可以理解为 只能出现在等号右边的变量(或表达式)。

  • 常见的右值有 字面量、函数返回的临时对象,匿名对象等。
  • 以上判断一个对象是左值还是右值并不完全正确。
const int c_a = 10;        //左值,但是不能被赋值,也就不能出现在 = 左边
//字符串字面值,可以取地址,是左值,但是也不能位于等号左边
&("我只左值");                //正确
//有时候右值是可以位于等号左边的
string s1, s2;
s1 + s2 = "它是右值但是能被赋值“;

3、右值引用(rvalue referrence):是C++11引入的一个新类型。右值有一下特性:

  • 可以直接绑定到右值。
  • 不能直接绑定到左值。
  • 本身是一个左值。可以进行 &运算。
  • 右值能被 const 类型的引用绑定。
  • 可以使用move()将左值绑定到右值引用上。
int a = 10;
int &b = a;    
int &&c = a * 10;       //右值引用直接绑定右值
const int &d = a * 20;    //右值引用绑定到const型引用
int &&e = a;          //错误。无法将右值引用绑定到左值 int *f = &e; //右值引用可以进行&运算 int &&g = move(a);     //使用move()将左值绑定到右值引用上
  • 可以使用move()将左值绑定到右值引用上。
  • std::forward()。 函数原型:std::forward<T>(u) 有两个参数:T 与 u。当T为左值引用类型时,u将被转换为T类型的左值,否则u将被转换为T类型右值。如此定义std::forward是为了在使用右值引用参数的函数模板中解决参数的完美转发问题。
//forward
template<typename _Tp>  
  inline _Tp&&  
  forward(typename std::remove_reference<_Tp>::type& __t)   
  { return static_cast<_Tp&&>(__t); }  


int a = 10;
int &b = forward<int &>(a);    //返回左值引用
int &&c = forward<int &&>(a);   //返回右值引用
int &&d = forward<int>(a);     //返回右值引用

猜你喜欢

转载自www.cnblogs.com/peformer/p/9087360.html