std::move源码分析

一、std::move的定义

下面定义截取自gcc源码:

/**
 *  @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); }

函数的注释表明以下几点:

  • 此函数用于将一个值转化为一个右值(注意这里没有说是左值还是右值)
  • __t是任意类型的参数
  • 此函数最终会将__t转化为一个右值引用类型

二、std::remove_reference的定义

std::remove_reference也是个函数模板,从名称上就比较好理解,即为移除引用。所以我们只想知道,它是如何移除引用的。
我们来看下std::remove_reference的定义:

/// remove_reference
template<typename _Tp>
  struct remove_reference
  { typedef _Tp   type; };

template<typename _Tp>
  struct remove_reference<_Tp&>
  { typedef _Tp   type; };

template<typename _Tp>
  struct remove_reference<_Tp&&>
  { typedef _Tp   type; };

从上面的定义我们可以看到无论传入的是值类型(_Tp),左值引用类型(_Tp&)还是右值引用类型(_Tp&&),最终得到的remove_reference<_Tp>::type都是_Tp类型,具体参考https://compiler-explorer.com/z/E86M68r3d。

三、综合分析

template<typename _Tp>
  constexpr typename std::remove_reference<_Tp>::type&&
  move(_Tp&& __t) noexcept
  { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }

std::move的参数被定义为万能引用的形式_Tp&& __t,这样std::move就可以接受所有的参数类型,而返回值始终是右值引用的类型。下面我们逐个进行解释,可以参考Item 1: 理解模板类型推导
这里假设std::move的调用形式为

auto expire = std::move(expr);
  • 如果expr为左值的话,会导致_Tp被推导为左值引用,假设类型为int,那么type(_Tp)==int&,根据引用折叠原理type(__t)==int&
  • 如果expr为右值(将亡值、纯右值),_Tp的推导会忽略引用部分type(_Tp)==int, 那么type(__t)=int&

无论type(_Tp)==int&还是type(_Tp)==intstd::remove_reference<_Tp>::type&&的返回类型都会是int&&

参考

  1. std::move实现详解
  2. C++ 完美转发
  3. cpp-reference的move
  4. std::move源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值