码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-05-25 13:37:01      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:除了   直接   const   style   class   col   color   表达   判断   

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()将左值绑定到右值引用上。
  • move调用告诉编译器:我们有一个左值,但我们希望像一个右值一样处理它。我们必须认识到,调用move就意味着承诺:除了对rr1赋值或销毁它外,我们将不再使用它在调用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);     //返回右值引用

 

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

标签:除了   直接   const   style   class   col   color   表达   判断   

原文地址:https://www.cnblogs.com/peformer/p/9087360.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!