四. 附注
左值和左值引用,右值和右值引用都是同一个东西,引用不是一个新的类型,仅仅是一个别名。这一点对于理解模板推导很重要。对于以下两个函数
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++教程频道。










