std::move(t)負責將t的類型轉換爲右值引用,這種功能頗有用,能夠用在swap中,也能夠用來解決完美轉發。c++
std::move()的源碼以下spa
template<class _Ty> inline _CONST_FUN typename remove_reference<_Ty>::type&& move(_Ty&& _Arg) _NOEXCEPT { // forward _Arg as movable return (static_cast<typename remove_reference<_Ty>::type&&>(_Arg)); }
先說一下實參爲左值的狀況。code
按理來講左值是沒法匹配右值形參的,可是c++爲了move這個基礎設施開了兩個例外。blog
第一個例外是當形參爲右值引用,實參爲左值時,編譯器推斷模板類型參數爲實參的左值引用類型。好比rem
template<typename T> void f(T&&); int i; f(i);
這樣編譯器推斷T爲int &類型。編譯器
可是按以前的規定,咱們並不能直接定義引用的引用,因而有了第二個例外——引用摺疊。源碼
引用摺疊的規則以下:it
& & == & && == && & == &編譯
&& && == &&ast
有了這兩個例外,move就能夠接受任何類型的實參,從而得到一個右值引用。
std::forward()源碼以下:
template<class _Ty> inline _CONST_FUN _Ty&& forward( typename remove_reference<_Ty>::type& _Arg) _NOEXCEPT { // forward an lvalue as either an lvalue or an rvalue return (static_cast<_Ty&&>(_Arg)); }
forward()必須經過顯式模板實參來調用,並返回該顯示模板實參的右值引用。好比std::forward<T>的返回類型爲T&&。
forward的使用一般以下:
template<class T> void fwd(T&& t) { foo(std::forward<T>(t)); }
若實參爲左值,根據引用摺疊,T爲左值引用,則執行foo()的實參爲左值引用;若實參爲右值,則執行foo()的實參爲右值引用,符合完美轉發。