当
给定以下简单的struct
template <typename T>
struct A
{
A(T a) {}
template <typename ... Ts>
A(T a, Ts ... more) {}
};
int main()
{
A<int> a(1);
}
什么保证A(T a)
将被调用而不是可变模板构造函数,为什么?
您要查找的标准中的部分是§14.8.2.4
如果A是从函数参数包转换而来的,而p不是参数包,则类型推导失败。否则,使用生成的类型P和A,然后按照14.8.2.5中所述进行推导。如果P是函数参数包,参数模板的每个剩余参数类型的类型a为与函数参数包的声明符id的类型P相比。每次比较推断函数展开的模板参数包中后续位置的模板参数参数包。如果给定类型的推导成功,则考虑参数模板中的类型至少与参数模板中的类型一样专业化。
[示例:
template<class... Args> void f(Args... args); // #1 template<class T1, class... Args> void f(T1 a1, Args... args); // #2 template<class T1, class T2> void f(T1 a1, T2 a2); // #3 f(); // calls #1 f(1, 2, 3); // calls #2 f(1, 2); // calls #3; non-variadic template #3 is more // specialized than the variadic templates #1 and #2
--结束示例]
T
可以推导为int
时,f(const int&)
比f(const T&)
更好匹配的原因是相同的:A(int)
是一个非模板函数,A(int, Ts...)
和Ts...
推导为空列表是一个函数模板专门化。