C++11--右值引用(Perfect Forwarding)
阿新 • • 發佈:2018-12-30
/* * 右值引用 2: Perfect Forwarding */ void foo( boVector arg ); // boVector既有移動構造又有拷貝構造 template< typename T > void relay(T arg ) { foo(arg); } int main() { boVector reusable = createBoVector(); relay(reusable); ... relay(createBoVector()); } // 什麼才能叫完美傳遞,Perfect Forwarding /* * 1. 沒有昂貴且不必要的拷貝構造 * 2. 右值傳遞為右值,左值傳遞為左值 */ // 解決方法: template< typename T > void relay(T&& arg ) { foo( std::forward<T>( arg ) ); } //* 注意:之所有有效是因為,型別T是模板型別 /* * 引用摺疊的規則 ( C++ 11 ): * 1. T& & ==> T& * 2. T& && ==> T& * 3. T&& & ==> T& * 4. T&& && ==> T&& //只有兩個右值引用還是右值引用 */ template< classs T > struct remove_reference; // 移除型別T的引用 // T為int& remove_refence<int&>::type i; // int i; // T為int remove_refence<int>::type i; // int i; template< typename T > void relay(T&& arg ) { ... } /* * 右值引用由type&&指定 * * 那麼type&&表示右值引用? */ // T&&變數以右值 => 右值引用 relay(9); => T = int&& => T&& = int&& && = int&& // T&&變數以左值初始化 => 左值引用 relay(x); => T = int& => T&& = int& && = int& // T&&是一個通用引用: 左值,右值,const,non-const等 // 前提條件: // 1. T是一個模板型別 // 2. T發生了型別摺疊 // - T 是函式模板型別,不是類模板了型別 template< typename T > void relay(T&& arg ) { foo( std::forward<T>( arg ) ); // 將arg轉回T&&型別 } // std::forward()的實現 template<class T> T&& forward(typename remove_reference<T>::type& arg) { return static_cast<T&&>(arg); } // std::move()和std::forward()比較 std::move<T>(arg); // 將arg變成一個右值類 std::forward<T>(arg); // 將arg變成T&&型別 /* * 總結: * * 右值引用兩個主要使用地方: * 1. 移動語義 * 2. 完美傳遞 */