http://blog.csdn.net/big_yellow_duck/article/details/52224068
看大黃鴨的《Effective Modern C++》翻譯時(shí),第9款最后有一小部分沒有翻,于是去看英文版補(bǔ)全,
看的時(shí)候順便翻譯了一下。然后今天校對過后把它發(fā)出來。
條款9 理解模板類型推斷 (最后小半部分)
如果你做過模板元編程(templete meta PRogramming, TMP),你肯定會遇到過要把模板類型轉(zhuǎn)換為其他類型的需求。例如,對于類型T,你可能想要去除T含有的const 修飾或者引用修飾,具體來說,比如你可能會想把const string& 變成std::string。或者你也有可能想把一個(gè)類型加上const修飾或者左值引用修飾,具體來說,比如把Widget變成const Widget或者Widget&。(如果你還沒有碰到過模板元編程,那可真是太糟糕了,因?yàn)槿绻阆氤蔀檎嬲咝У腃++程序員,你就需要對c++的這一塊至少有最基本的了解。你會在條款25和條款29中也看到TMP的例子,其中也包含了我在上面提及到的類型轉(zhuǎn)換。
c++11提供了實(shí)行這樣轉(zhuǎn)換的工具,他們叫做type traits,是一種變形的模板類,包含在頭文件<type_traits>中。這個(gè)頭文件中有一打這樣的type traits,但并不是所有的都是處理類型轉(zhuǎn)換相關(guān),其中的一些提供了望文而知意的接口。假設(shè)你要轉(zhuǎn)換的源類型為T,你需要的轉(zhuǎn)換結(jié)果就是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
上面的注釋只是簡單說明代碼做了什么。不要在意我的修辭手法。不過在把他們用到工程中之前,你一定去會仔細(xì)查閱他們的說明文檔的,這我知道。
不過我在這里的原意也不是上一堂關(guān)于type traits的教學(xué)課。我請你注意到這些轉(zhuǎn)換接口的末尾都帶有“::type”的后綴。如果你用它們在模板內(nèi)部作為參數(shù)傳遞(實(shí)際上你總是這樣使用它們),你也不得不在每個(gè)前面加上一個(gè)“typename”。會出現(xiàn)這樣像是馬路兩邊的“路牙”的玩意,是因?yàn)閏++11的type traits的實(shí)現(xiàn),是基于模板化結(jié)構(gòu)的內(nèi)部嵌套typedef。沒錯(cuò),那就是我曾經(jīng)極力向你推薦的類型變化技巧,現(xiàn)在他們輸給了模板別名(alias template)!!(譯注:即using關(guān)鍵字)
c++11這樣做是有歷史原因的,不過我們先跳過他們(說明很無趣,我保證)。長話短說,因?yàn)閏++標(biāo)準(zhǔn)化委員會終于認(rèn)識到模板別名是更好的實(shí)現(xiàn)方案,他們于是先在c++14里為這些c++11風(fēng)格的類型轉(zhuǎn)換做了一層包裝。包裝具有如下形式:對每個(gè)c++11形如std::transformation<T>::type的轉(zhuǎn)換接口,就有一個(gè)與之對應(yīng)的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,你自己寫一個(gè)模板別名也是小菜一碟。這只需要用到c++11的語言特性,連三歲小孩也能做到的,相信我。即使你能拿到一份c++14標(biāo)準(zhǔn)案的拷貝,也還是自己寫比較簡單,因?yàn)樗心阋龅木褪强截愓迟N。我會給你起個(gè)頭(也是通過拷貝粘貼):
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;
你瞧,簡單得不能再簡單了吧。
新聞熱點(diǎn)
疑難解答
圖片精選