C++11 移動語義和完美轉發
阿新 • • 發佈:2019-01-24
所謂的移動語義即就是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)。