詳解C++17中類模板參數(shù)推導(dǎo)的使用
在C++17之前,必須明確指出類模板的所有參數(shù)。自從C++17起必須指明類模板參數(shù)的限制被放寬了。通過(guò)使用類模板參數(shù)推導(dǎo)(Class Template Argument Deduction(CTAD)),只要編譯器能根據(jù)初始值推導(dǎo)出所有模板參數(shù),那么就可以不指明參數(shù)。
C++17中的類模板參數(shù)推導(dǎo):允許從構(gòu)造函數(shù)參數(shù)推導(dǎo)模板參數(shù),簡(jiǎn)而言之,編譯器可以根據(jù)構(gòu)造函數(shù)參數(shù)自動(dòng)推導(dǎo)它們,而不是顯式指定模板參數(shù)。
用戶定義的推導(dǎo)指南(User-defined deduction guides):允許你為類模板參數(shù)推導(dǎo)提供自定義規(guī)則。這些指南幫助編譯器根據(jù)構(gòu)造函數(shù)參數(shù)推斷模板參數(shù)。
別名模板的推導(dǎo)(deduction for alias templates):允許你根據(jù)別名模板的基礎(chǔ)類型或值(underlying type or value)推導(dǎo)別名模板的模板參數(shù)。
注意:
(1).推導(dǎo)過(guò)程中模板參數(shù)必須沒有歧義。
(2).推導(dǎo)模板參數(shù)時(shí)不會(huì)使用隱式類型轉(zhuǎn)換。
(3).僅當(dāng)不存在模板參數(shù)列表時(shí)才執(zhí)行類模板參數(shù)推導(dǎo)。如果指定了模板參數(shù)列表,則不會(huì)發(fā)生推導(dǎo)。
(4).類模板參數(shù)推導(dǎo)過(guò)程中會(huì)首先嘗試以拷貝的方式初始化。
(5).類模板不能只指明一部分模板參數(shù),然后指望編譯器去推導(dǎo)剩余的部分參數(shù)。
(6).在任何情況下,對(duì)于像std::vector<>或其他STL容器一樣擁有復(fù)雜的構(gòu)造函數(shù)的類模板,強(qiáng)烈建議不要使用類模板參數(shù)推導(dǎo),而是顯式指明類型。
(7).智能指針沒有推導(dǎo)指引。
以下為測(cè)試代碼:
namespace { template<typename T> class Foo { public: Foo(T value) { std::cout << "Created Foo, type id: " << typeid(T).name() << ", value: " << value << "\n"; } }; template<typename T> class Foo2 { public: Foo2(T value) { std::cout << "Created Foo2, type id: " << typeid(T).name() << ", value: " << value << "\n"; } }; // User-defined deduction guide template<typename T> Foo2(T)->Foo2<T>; template<typename T> using MyAlias = T; template<typename T> class Foo3 { public: Foo3(const std::initializer_list<T>& list) : vec_(list) {} void print() const { for (const auto& val : vec_) { std::cout << val << " "; } std::cout << "\n"; } private: std::vector<T> vec_; }; } // namespace int test_ctad() { // 只要能根據(jù)初始值推導(dǎo)出所有模板參數(shù)就可以使用類模板參數(shù)推導(dǎo) // 推導(dǎo)過(guò)程支持所有方式的初始化(只要保證初始化是有效的) std::pair p(2, 4.5); // deduces to std::pair<int, double> p(2, 4.5); std::tuple t(4, 3, 2.5); // same as auto t = std::make_tuple(4, 3, 2.5); std::complex c{ 5.1, 3.3 }; // std::complex<double> std::mutex mx; std::lock_guard lg{ mx }; // std::lock_guard<std::mutex> std::vector vec{ "hello", "world" }; // std::vector<const char*> std::vector v1{ 42 }; std::vector v2{ v1 }; // v2也是一個(gè)std::vector<int>,這是花括號(hào)初始化總是把列表中的參數(shù)作為元素這一規(guī)則的一個(gè)例外 // 然而,如果用多于一個(gè)元素的初值列來(lái)初始化的話,就會(huì)把傳入的參數(shù)作為元素并推導(dǎo)出其類型作為模板參數(shù) std::vector vv{ v1, v2 }; // vv是一個(gè)vector<vector<int>> // 1.Class Template Argument Deduction(CTAD) // not specifying the type of the template auto foo11 = Foo(88); // Created Foo, type id: int, value: 88 auto foo12 = Foo("Beijing"); // Created Foo, type id: char const * __ptr64, value: Beijing // specifying the type of the template Foo<int> foo21(88); // Created Foo, type id: int, value: 88 Foo<const char*> foo22("Beijing"); // Created Foo, type id: char const * __ptr64, value: Beijing // 2.User-defined deduction guides // not specifying the type of the template auto foo31 = Foo2(88); // Created Foo2, type id: int, value: 88 auto foo32 = Foo2("Beijing"); // Created Foo2, type id: char const * __ptr64, value: Beijing // 3.the deduction for alias templates MyAlias<int> alias1{ 88 }; MyAlias<std::string> alias2{ "Beijing" }; std::cout << "alias1: " << alias1 << "\n"; // alias1: 88 std::cout << "alias2: " << alias2 << "\n"; // alias2: Beijing // reference: https://www.geeksforgeeks.org/class-template-argument-deduction-in-cpp-17/ auto foo41 = Foo3({ 1, 2, 3, 4, 5 }); foo41.print(); // 1 2 3 4 5 return 0; }
執(zhí)行結(jié)果如下圖所示:
GitHub:https://github.com/fengbingchun/Messy_Test
到此這篇關(guān)于詳解C++17中類模板參數(shù)推導(dǎo)的使用的文章就介紹到這了,更多相關(guān)C++17類模板參數(shù)推導(dǎo)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中的結(jié)構(gòu)體的入門學(xué)習(xí)教程
這篇文章主要介紹了C語(yǔ)言中的結(jié)構(gòu)體的入門學(xué)習(xí)教程,以struct語(yǔ)句定義的結(jié)構(gòu)體是C語(yǔ)言編程中的重要基礎(chǔ),需要的朋友可以參考下2015-12-12C語(yǔ)言實(shí)現(xiàn)教務(wù)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)教務(wù)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03淺析C語(yǔ)言中對(duì)于char*和char[]的理解
char * s 只是一個(gè)保存字符串首地址的指針變量,char a[]是許多連續(xù)的內(nèi)存單元,單元中的元素是char型,char * 和 char a[]具有相同的效果,源于字符串的本質(zhì),這篇文章主要介紹了C語(yǔ)言中對(duì)于char*和char[]的理解,需要的朋友可以參考下2023-02-02C++中高性能內(nèi)存池的實(shí)現(xiàn)詳解
在 C/C++ 中,內(nèi)存管理是一個(gè)非常棘手的問題,我們?cè)诰帉懸粋€(gè)程序的時(shí)候幾乎不可避免的要遇到內(nèi)存的分配邏輯。本文將通過(guò)C++實(shí)現(xiàn)高性能內(nèi)存池,感興趣的可以了解一下2022-10-10C++獲取字符串長(zhǎng)度的幾個(gè)函數(shù)方式
這篇文章主要介紹了C++獲取字符串長(zhǎng)度的幾個(gè)函數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12C語(yǔ)言深入講解語(yǔ)句與選擇結(jié)構(gòu)的使用
這篇文章主要為大家介紹了C語(yǔ)言的語(yǔ)句與選擇結(jié)構(gòu),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05