在temp.deduct.partial中,为什么参数包没有那么专业?

kna*_*ten 9 c++ templates c++17

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
Run Code Online (Sandbox Code Playgroud)

调用#1很简单,因为只有一个可行的专业化。

对于呼叫#2,f?f?是可行的。我们合成f?(X)f?(X, Y)。然后,我们同时进行两种类型的推导。

首先f?(X, Y)反对f?(Args... args),推论ArgsX, Y

然后f?(X)针对void f?(T1 a1, Args... args),它推导T1XArgs为空。

因此,推论在两种方式上都是成功的,而且没有一种比另一种更专业。

我们可以通过temp.deduct.partial#11保存吗?

在考虑上述因素后,如果功能模板F至少与功能模板G一样专业,反之亦然,并且G的尾随参数包中F没有对应的参数,并且F没尾随参数包,则F比G更专业。

看起来没有帮助。让F=f?, G=f?,那么G确实有其尾参数包F不具有相应的参数。但是F具有尾随参数包,因此这并不适用。

我是否误读了标准中的任何内容,还是可能完全在其他地方找到答案?

kna*_*ten 3

西蒙·布兰德在推特上对此做出了回应。关键在temp.deduct#type-10.2

\n\n
\n

在部分排序过程中,如果 Ai 原本是函数参数包:\n (...) 如果 Pi 不是函数参数包,则模板参数推导失败。

\n
\n\n

在这种情况下,在做f\xe2\x82\x81(X)against时f\xe2\x82\x82(T1 a1, Args... args)X原本是一个函数参数包。T1但不是函数参数包,因此推导失败。

\n\n

因为我们可以f\xe2\x82\x81从推导出来f\xe2\x82\x82,但反之则不然,f\xe2\x82\x82因此更加专业化。

\n