左值右值右值引用与move()forward()
Posted 舆马者的悲伤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了左值右值右值引用与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()将左值绑定到右值引用上。
-
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()的主要内容,如果未能解决你的问题,请参考以下文章