C++ std::move, std::forward

C++ std::move, std::forward

一、摘要

​ 本文主要是针对std::move 和std::forward 转换原理和功能特性进行阐述,我比较喜欢从源码的方式进行,这个比较直观并且更能够明白实现细节

二、右值引用解析规则

转换规则1:

引用表达式解析等价结果
A& &A&
A& &&A&
A&& &A&
A&& &&A&&

引用转换规则2:

template<typename T>
void foo(T&&);

int a = 0;
foo(a); // 当传入参数为左值是,T 解析为 int& 在通过规则1 转换后变为int &
foo(0); // 当传入参数为右值时,T 解析为 int

三、std::move 和 std::forward源码解读

//remove_reference 改类的作用主要是移除模板解析的类型所附加的属性(&, &&)
template<class _Ty>
	struct remove_reference
	{	// remove reference
	using type = _Ty;
	};

template<class _Ty>
	struct remove_reference<_Ty&>
	{	// remove reference
	using type = _Ty;
	};

template<class _Ty>
	struct remove_reference<_Ty&&>
	{	// remove rvalue reference
	using type = _Ty;
	};

template<class _Ty>
	using remove_reference_t = typename remove_reference<_Ty>::type;
//std::move 从源码上就可以看到无论传入参数是lvalue或rvalue该函数将会通过static_cast强制转换为rvalue
template<class _Ty>
constexpr remove_reference_t<_Ty>&&
    move(_Ty&& _Arg) noexcept
{	// forward _Arg as movable
    return (static_cast<remove_reference_t<_Ty>&&>(_Arg));
}
/*
*std::forward 相对要复杂一点可以分开进行分析(forward不支持类型自动推演方式,需要转换后强制指定类型)
*/
template<class _Ty>
constexpr _Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept
{	// forward an lvalue as either an lvalue or an rvalue
    return (static_cast<_Ty&&>(_Arg));
}

template<class _Ty>
constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept
{	// forward an rvalue as an rvalue
    static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call");
    return (static_cast<_Ty&&>(_Arg));
}

//demo 对forward转换原理进行描述
template<class T>
void foo(T && value)
{
    std::forward<T>(value);
}

foo(3); //T 被解析为int, value 是lvalue 所以调用第一个函数 forward后得到的结果还是一个右值,等同于move
int a = 3;
foo(a); // T被解析为 int&,value是lvalue 所以调用第一个函数 forward后根据规则一forward转换后变为一个lvalue

四、参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值