std::move()和std::forward()

  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()的實參爲右值引用,符合完美轉發。

相關文章
相關標籤/搜索