C++学习之std::move()和std::forward()

C++11通过std::move()和std::forward()函数分别实现了左值转右值和完美转发的功能。
对于std::move(),考虑如下情形:

    void func(int &&args) {

      std::cout << args << std::endl;

  }

  int a = 10;

  func(20);    // ok

  func(a);      // error, 右值引用不能绑定左值

  func(std::move(a));    // ok

对于std::forward(),完美转发,当

    void func(int &arg) {
       std::cout << "func lvalue" << std::endl;
   }

   void func(int &&arg) {
       std::cout << "func rvalue" << std::endl;
   }

   template <typename T>
   void wrapper(T &&args) {
       func(args);
   }

   int main() {
       int a = 10; 

       wrapper(a);
       wrapper(20);

       return 0;
   }
  以上函数输出:

    func lvalue
    func lvalue

虽然我们调用wrapper()函数时,传入的参数一个是左值,一个是右值,但是最终的输出确都是左值。原因是我们在中间加了一层转发函数wrapper()。

引用叠加,引用是可以叠加的,对于 T &&a; 叠加规则如下:

(1)当T类型为 Type 时,a 为 Type &&a,右值引用。

(2)当T类型为 Type& 时,a为 Type &a,左值引用。

(3)当T类型为 Type&& 时,a为 Type &&a,右值引用。

通过引用叠加,分析以上示例可知,调用wrapper()时,wrapper(a) 是调用的原型是 wrapper(int &),是左值调用;wrapper(20)调用的原型是wrapper(int &&),是右值调用。但是在wrapper()函数内部,无论如何,args都是一个左值,在调用func()函数的时候,调用的func()原型总是func(int &)。

因此,根本原因其实是,右值引用属性不能被转发。所以,C++11提供了std::forward()函数用于完美转发。即,在转发过程中,左值引用在被转发之后仍然保持左值属性,右值引用在被转发之后依然保持右值属性。修改之后的代码如下:

 void func(int &arg) {
        std::cout << "func lvalue" << std::endl;
    }

    void func(int &&arg) {
        std::cout << "func rvalue" << std::endl;
    }

    template <typename T>
    void wrapper(T &&args) {
        func(std::forward<T>(args));
    }

    int main() {
        int a = 10; 

        wrapper(a);
        wrapper(20);

        return 0;
    }
如此,输出如下:

    func lvalue
    func rvalue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值