1. 程式人生 > >C++11 移動語義和完美轉發

C++11 移動語義和完美轉發

所謂的移動語義即就是transfer ownership,轉移所有權。

而move() 和 farward() 只不過是對型別轉換的一個包裝而已。(之前見到的將一個變數a 按T 型別來解釋的兩種方法 (T&) a   或者  *(T*)&a)

template<typename T>
inline typename std::remove_reference<T>::type&&
move(T&& t)
{
	return static_cast<typename std::remove_reference<T>::type &&>(t);
}

根據C++11中的型別推導和引用摺疊規則,T&&  表示的是一個萬能引用(universal reference), 即既可以是左值引用也可以是右值引用,根據例項化時 t 的型別來推斷。當T的型別是 U& 或者是 U&& 的時候(U是具體的型別)

typename std::remove_reference<T>::type

表示的型別是U,即字面上的意思,去掉型別上的引用。

返回的是一個右值,這個右值的型別是右值引用。(具名的右值引用是左值,無名的右值引用是右值。而左值引用,無論是有名還是無名,都是左值。)

另外需要注意的時,用引用變數來繫結一個臨時物件(是右值), 無論是左值引用(只能是const左值引用)還是右值引用型別來繫結,會延長臨時物件的生命週期,使得引用變數存活的期間, 臨時變數也存在。


template<typename T>
inline T&&
forward(typename std::remove_reference<T>::type& t)
{
	return static_cast<T&&>(t);
}

使用的時候,forward<U&>() 時, 返回值的型別是U&; forward<U&&>() 時,返回值的型別是U&& , 從而達到不丟失變數左值還是右值的屬性。

具體程式碼是這樣, 通過函式函式g() 完美的將引數轉發給了 f(),達到呼叫函式g() 跟f()完全相同的效果.

template<class T>
void g(T &&a)
{
	f(forward<T>(a));

完美轉發forward<> 使用時,需要顯示例項化forward<T> (arg)。