std::move(t)負責將t的類型轉換為右值引用,這種功能很有用,可以用在swap中,也可以用來解決完美轉發。
std::move()的源碼如下
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)); }
先說一下實參為左值的情況。
按理來說左值是無法匹配右值形參的,但是c++為了move這個基礎設施開了兩個例外。
第一個例外是當形參為右值引用,實參為左值時,編譯器推斷模板類型參數為實參的左值引用類型。比如
template<typename T> void f(T&&); int i; f(i);
這樣編譯器推斷T為int &類型。
但是按之前的規定,我們並不能直接定義引用的引用,於是有了第二個例外——引用折疊。
引用折疊的規則如下:
& & == & && == && & == &
&& && == &&
有了這兩個例外,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()的實參為右值引用,符合完美轉發。