在temp.deduct.partial#8中,有一个示例:
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
由于只有一个可行的专业化,因此#1通话是微不足道的。
对于呼叫2,f₁
和f₂
是可行的。我们合成了f₁(X)
和f₂(X, Y)
。然后,我们同时进行两种类型的推导。
针对f₂(X, Y)
的第一个f₁(Args... args)
,推论出Args
为X, Y
。
然后f₁(X)
对无效f₂(T1 a1, Args... args)
,其将T1
推论为X
,将Args
推论为空。
所以推论在两种方式上都成功,而且没有一种比另一种更专业。
我们可以由temp.deduct.partial#11保存吗?
如果在考虑了上述内容后,功能模板F至少与功能模板G一样专门,反之亦然,并且G的尾随参数包中F没有对应的参数,并且F没有有一个尾随参数包,那么F比G更专业。
看起来没有帮助。让F=f₁, G=f₂
,则G
确实具有尾随参数包,而F
没有尾随参数包。但是F
有一个尾随参数包,因此这并不适用。
我是否误读了标准中的任何内容,或者答案可能完全在其他地方找到了?
答案 0 :(得分:1)
这是Simon Brand的answered在Twitter上。密钥在temp.deduct#type-10.2中:
在部分订购期间,如果Ai最初是一个功能参数包: (...)如果Pi不是函数参数包,则模板参数推导失败。
在这种情况下,对f₁(X)
执行f₂(T1 a1, Args... args)
时,X
最初是一个函数参数包。 T1
不是函数参数包,因此推导失败。
由于我们可以从f₁
推论f₂
,但不能反过来,所以f₂
更加专业。