C++ 完美轉發

完美轉發實現了參數在傳遞過程中保持其值類別的功能,即,若是左值,則傳遞之後仍然是左值,若是右值,則傳遞之後仍然是右值。

forawrd 的函數聲明爲:

template< class T >
T&& forward( typename std::remove_reference<T>::type& t ) noexcept;

template< class T >
T&& forward( typename std::remove_reference<T>::type&& t ) noexcept;

std::remove_reference<T>

其定義爲:

template< class T > struct remove_reference      {typedef T type;};
template< class T > struct remove_reference<T&>  {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};

其作用便是去除類型模板形參中的引用。如:

remove_reference<int>::type => int
remove_reference<int&>::type => int
remove_reference<int&&>::type => int

引用摺疊規則

右值引用的右值引用會摺疊爲右值引用,其他情況下,全部摺疊爲左值引用。

typedef int&  lref;
typedef int&& rref;

int n;

lref&  r1 = n; // type of r1 is int&
lref&& r2 = n; // type of r2 is int&
rref&  r3 = n; // type of r3 is int&
rref&& r4 = 1; // type of r4 is int&&

分析

設 T 的實際類型(經推斷/顯式指定)爲 A,以下以 int 類型爲例。

如果 A 爲 int,則 forward 的返回值類型爲 int&&

如果 A 爲 int&,則 forward 的返回值類型爲 int& &&,經引用摺疊之後,返回值類型爲 int&

如果 A 爲 int&&,則 forward 的返回值類型爲 int&& &&,經引用摺疊之後,返回值類型爲 int&&

此外,模板實參推斷規則中有一條爲:如果形參是一個非 const/volatile 修飾的右值引用,且函數調用時傳遞的實參是一個左值,設其類型爲 int,那麼 A 便爲 int&

例子:

template<class T>
void wrapper(T&& arg)  {
    foo(std::forward<T>(arg));
}

int i = 1;
wrapper(i);		// T = int&,std::forward<T>(arg) 返回值類型爲 int&

wrapper(1);		// T = int,std::forward<T>(arg) 返回值類型爲 int&&

const ci = 1;
wrapper(ci);	// T = const int&,std::forward<T>(arg) 返回值類型爲 const int&
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章