深入解读C++中的右值引用

2020-01-06 15:15:48刘景俊

四. 附注
左值和左值引用,右值和右值引用都是同一个东西,引用不是一个新的类型,仅仅是一个别名。这一点对于理解模板推导很重要。对于以下两个函数


template<typename T>
void Fun(T t)
{
 // do something...
}

template<typename T>
void Fun(T& t)
{
 // do otherthing...
}

Fun(T t)和Fun(T& t)他们都能接受左值(引用),它们的区别在于对参数作不同的语义,前者执行拷贝语义,后者只是取个新的别名。因此调用Fun(a)编译器会报错,因为它不知道你要对a执行何种语义。另外,对于Fun(T t)来说,由于它执行拷贝语义,因此它还能接受右值。因此调用Fun(5)不会报错,因为左值引用无法引用到右值,因此只有Fun(T t)能执行拷贝。
最后,附上VS中 std::move 和 std::forward 的源码:


// move
template<class _Ty> 
inline typename remove_reference<_Ty>::type&& move(_Ty&& _Arg) _NOEXCEPT
{ 
 return ((typename remove_reference<_Ty>::type&&)_Arg);
}

// forward
template<class _Ty> 
inline _Ty&& forward(typename remove_reference<_Ty>::type& _Arg)
{ // forward an lvalue
 return (static_cast<_Ty&&>(_Arg));
}

template<class _Ty> 
inline _Ty&& forward(typename remove_reference<_Ty>::type&& _Arg) _NOEXCEPT
{ // forward anything
 static_assert(!is_lvalue_reference<_Ty>::value, "bad forward call");
 return (static_cast<_Ty&&>(_Arg));
}


注:相关教程知识阅读请移步到C++教程频道。