• C++之forward move源码分析


    /**
       *  @brief  Forward an lvalue.
       *  @return The parameter cast to the specified type.
       *
       *  This function is used to implement "perfect forwarding".
       */
      template<typename _Tp>
        constexpr _Tp&&
        forward(typename std::remove_reference<_Tp>::type& __t) noexcept
        { return static_cast<_Tp&&>(__t); }
    
      /**
       *  @brief  Forward an rvalue.
       *  @return The parameter cast to the specified type.
       *
       *  This function is used to implement "perfect forwarding".
       */
      template<typename _Tp>
        constexpr _Tp&&
        forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
        {
          static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
    		    " substituting _Tp is an lvalue reference type");
          return static_cast<_Tp&&>(__t);
        }

     主要说一下传入左值的情况,为啥返回的仍然是右值类型呢,说好的左值类型呢???

    这里就涉及到一个折叠的概念,简单理解就是&的个数偶数就是右值,奇数就是左值。

    明白了这个之后继续分析

    比如说传入的是int&,那么 _Tp = int&,那么_Tp&&展开后int&&&。是不是豁然开朗。折叠后就是引用啊。

    展开后的代码

    int&& intForward(int && value)
    {
        return static_cast<int &&>(value);
    }
    
    int& intForward(int & value)
    {
        return static_cast<int &>(value);
    }

    明白了这个咱再看下move的实现

     /**
       *  @brief  Convert a value to an rvalue.
       *  @param  __t  A thing of arbitrary type.
       *  @return The parameter cast to an rvalue-reference to allow moving it.
      */
      template<typename _Tp>
        constexpr typename std::remove_reference<_Tp>::type&&
        move(_Tp&& __t) noexcept
        { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }

    折叠之后的参数兼容了左值和右值,但是返回的时候是萃取到原始的类型,然后强制转换成右值进行返回。

    展开后的代码

    int&& intMove(int& value)
    {
        return  static_cast<int&&>(value);
    }

    返回值为啥会有个typename呢,因为返回值用到的模板参数,通过typename告诉编译器后面是个数据类型,不是别的,求放过。不用typename的话,编译器就不能理解它后面那个是个啥东西,编译报错。

    还用到了constexpr,这个是个啥呢,那就说来话长了。

    篇幅有限,下次继续

  • 相关阅读:
    Linux之定时器与时间管理 【转】
    LDAP研究
    Mac中使用svn进行项目管理
    英国调查报告称中国梦吸引力首超美国梦
    怎样删除在Github中创建的项目
    MySQL分组数据
    Eclipse ADT 插件安装慢的解决的方法
    iOS插件化研究之中的一个——JavaScriptCore
    二维码的妙用:通过Zxing实现wifi账号password分享功能
    CF(435D
  • 原文地址:https://www.cnblogs.com/xzlq/p/15257080.html
Copyright © 2020-2023  润新知