2016-12-03 42 views
36

C++ 17引入了「模板演繹指南」。我收集他們與這個版本的標準中引入的構造函數的新模板演繹有關,但我還沒有看到關於它們是什麼以及它們的用途的簡單的FAQ風格解釋。什麼是模板扣除指南,我們應該在什麼時候使用它們?

  • 什麼是C++ 17中的模板演繹指南?

  • 爲什麼(以及何時)我們需要它們?

  • 我該如何申報?

+3

http://en.cppreference.com/w/cpp/language/class_template_deduction – doug

+0

特別是,我很想知道是否有任何演繹指南實際上是由C++ 17 STL提供的(例如std: :pair或std :: tuple)。從C++ 17開始,完整的「可推導」標準模板類型列表是什麼? – Quuxplusone

+0

@Quuxplusone http://en.cppreference.com/w/cpp/utility/pair/deduction_guides和http://en.cppreference。com/w/cpp/utility/tuple/deduction_guides – Cubbi

回答

46

模板推導指南是與模板類相關的模式,它告訴編譯器如何將一組參數(及其類型)轉換爲模板參數。

最簡單的例子是std::vector及其構造函數,它需要一個迭代器對。

template<typename Iterator> 
void func(Iterator first, Iterator last) 
{ 
    vector v(first, last); 
} 

編譯器需要弄清楚vector<T>T類型是什麼。我們知道答案是什麼; T應該是typename std::iterator_traits<Iterator>::value_type。但是我們如何告訴編譯器沒有必須鍵入vector<typename std::iterator_traits<Iterator>::value_type>

您使用扣指南:

template<typename Iterator> vector(Iterator b, Iterator e) -> 
    vector<typename std::iterator_traits<Iterator>::value_type>; 

這告訴,當你調用一個vector構造匹配的模式,它會推斷使用上的->右邊的代碼vector專業化的編譯器。

當從參數中扣除類型不基於其中一個參數的類型時,您需要指南。從initializer_list初始化vector明確使用vectorT,因此它不需要指南。

左側不一定指定構造函數。它的工作方式是,如果您在類型上使用模板構造函數演繹,它會將您傳遞的參數與所有演繹指南(實際構造函數提供的隱式指南)進行匹配。如果匹配,它使用它來確定提供給該類型的模板參數。但重載決議確定調用哪個構造函數之後

這也意味着,你可以使用帶有集合和集合初始化指南:

template<typename T> 
struct Thingy 
{ 
    T t; 
}; 

Thingy(const char *) -> Thingy<std::string>; 

Thingy thing{"A String"}; //thing.t is a `std::string`. 

所以扣除導遊僅用於找出類型被初始化。一旦確定完成,實際的初始化過程就像以前一樣工作。

+3

嗯,剛纔我發現,即使在指南中,vector v {first,last};'也不會做正確的事情:( –

+6

@TC:這就是「統一初始化「爲你 –

+0

@TC ...除非正確的東西是製作一個迭代器的向量,而''std :: string {32,'*'} [0] ==''''(對於ASCII)。從C++ 11開始,這一切都是真實的 –

相關問題