zoukankan      html  css  js  c++  java
  • 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 shell中 if else以及大于、小于、等于逻辑表达式
    下载chrome插件和离线安装CRX文件的方法
    ROM、PROM、EPROM、EEPROM、FLASH ROM简介
    Scientific Toolworks Understand
    C和C++相互调用
    ubuntu 问题
    ubuntu 精简配置
    Linux i2c 读写程序
    是armhf,还是armel?
    Linux Free命令每个数字的含义 和 cache 、buffer的区别
  • 原文地址:https://www.cnblogs.com/xzlq/p/15257080.html
Copyright © 2011-2022 走看看