http://blog.csdn.net/big_yellow_duck/article/details/52224068
看大黃鴨的《Effective Modern C++》翻譯時,第9款最后有一小部分沒有翻,于是去看英文版補全,
看的時候順便翻譯了一下。然后今天校對過后把它發出來。
條款9 理解模板類型推斷 (最后小半部分)
如果你做過模板元編程(templete meta PRogramming, TMP),你肯定會遇到過要把模板類型轉換為其他類型的需求。例如,對于類型T,你可能想要去除T含有的const 修飾或者引用修飾,具體來說,比如你可能會想把const string& 變成std::string?;蛘吣阋灿锌赡芟氚岩粋€類型加上const修飾或者左值引用修飾,具體來說,比如把Widget變成const Widget或者Widget&。(如果你還沒有碰到過模板元編程,那可真是太糟糕了,因為如果你想成為真正高效的C++程序員,你就需要對c++的這一塊至少有最基本的了解。你會在條款25和條款29中也看到TMP的例子,其中也包含了我在上面提及到的類型轉換。
c++11提供了實行這樣轉換的工具,他們叫做type traits,是一種變形的模板類,包含在頭文件<type_traits>中。這個頭文件中有一打這樣的type traits,但并不是所有的都是處理類型轉換相關,其中的一些提供了望文而知意的接口。假設你要轉換的源類型為T,你需要的轉換結果就是std::transformation<T>::type。例如:
std::remove_const<T>::type // yields T from const T
std::remove_reference<T>::type // yields T from T& and T&&
std::add_lvalue_reference<T>::type // yields T& from T
上面的注釋只是簡單說明代碼做了什么。不要在意我的修辭手法。不過在把他們用到工程中之前,你一定去會仔細查閱他們的說明文檔的,這我知道。
不過我在這里的原意也不是上一堂關于type traits的教學課。我請你注意到這些轉換接口的末尾都帶有“::type”的后綴。如果你用它們在模板內部作為參數傳遞(實際上你總是這樣使用它們),你也不得不在每個前面加上一個“typename”。會出現這樣像是馬路兩邊的“路牙”的玩意,是因為c++11的type traits的實現,是基于模板化結構的內部嵌套typedef。沒錯,那就是我曾經極力向你推薦的類型變化技巧,現在他們輸給了模板別名(alias template)?。。ㄗg注:即using關鍵字)
c++11這樣做是有歷史原因的,不過我們先跳過他們(說明很無趣,我保證)。長話短說,因為c++標準化委員會終于認識到模板別名是更好的實現方案,他們于是先在c++14里為這些c++11風格的類型轉換做了一層包裝。包裝具有如下形式:對每個c++11形如std::transformation<T>::type的轉換接口,就有一個與之對應的C++14 模板別名std::transformation_t。看例子就知道我說的意思了。
std::remove_const<T>::type // C++11: const T → T
std::remove_const_t<T> // C++14 equivalent
std::remove_reference<T>::type // C++11: T&/T&& → T
std::remove_reference_t<T> // C++14 equivalent
std::add_lvalue_reference<T>::type // C++11: T →T&
std::add_lvalue_reference_t<T> // C++14 equivalent
c++11形式的接口在c++14里還能用,不過我想不出你還有什么理由用他們。即使你沒有c++14,你自己寫一個模板別名也是小菜一碟。這只需要用到c++11的語言特性,連三歲小孩也能做到的,相信我。即使你能拿到一份c++14標準案的拷貝,也還是自己寫比較簡單,因為所有你要做的就是拷貝粘貼。我會給你起個頭(也是通過拷貝粘貼):
template <class T>using remove_const_t = typename remove_const<T>::type;
template <class T>using remove_reference_t = typename remove_reference<T>::type
template <class T>using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
你瞧,簡單得不能再簡單了吧。
新聞熱點
疑難解答
圖片精選