模板推导指南是与模板类关联的模式,它告诉编译器如何将一组构造函数参数(及其类型)转换为该类的模板参数。
最简单的例子是std::vector
及其采用迭代器对的构造函数。
template<typename Iterator>
void func(Iterator first, Iterator last)
{
vector v(first, last);
}
编译器需要弄清楚什么vector<T>
's T
类型将是。我们知道答案是什么;T
应该typename std::iterator_traits<Iterator>::value_type
。但是我们如何告诉编译器without必须打字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
使用右侧的代码进行专业化->
.
当从参数中推导类型不基于这些参数之一的类型时,您需要指南。初始化一个vector
从一个initializer_list
明确使用vector
's T
,所以它不需要指南。
左侧不一定指定实际的构造函数。它的工作方式是,如果您在类型上使用模板构造函数推导,它会匹配您针对所有推导指南传递的参数(主模板的实际构造函数提供隐式指南)。如果存在匹配,它会使用它来确定向该类型提供哪些模板参数。
但是,一旦推导完成,一旦编译器计算出该类型的模板参数,该类型的对象的初始化就会继续进行,就好像这一切都没有发生一样。也就是说,选择的演绎指南不必与构造函数已选择。
这也意味着您可以使用具有聚合和聚合初始化的指南:
template<typename T>
struct Thingy
{
T t;
};
Thingy(const char *) -> Thingy<std::string>;
Thingy thing{"A String"}; //thing.t is a `std::string`.
因此推导指南仅用于找出正在初始化的类型。一旦做出决定,初始化的实际过程就会像以前一样进行。