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),推论Args为X, Y。
然后f?(X)针对void 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具有尾随参数包,因此这并不适用。
我是否误读了标准中的任何内容,还是可能完全在其他地方找到答案?
西蒙·布兰德在推特上对此做出了回应。关键在temp.deduct#type-10.2:
\n\n\n\n\n在部分排序过程中,如果 Ai 原本是函数参数包:\n (...) 如果 Pi 不是函数参数包,则模板参数推导失败。
\n
在这种情况下,在做f\xe2\x82\x81(X)against时f\xe2\x82\x82(T1 a1, Args... args),X原本是一个函数参数包。T1但不是函数参数包,因此推导失败。
因为我们可以f\xe2\x82\x81从推导出来f\xe2\x82\x82,但反之则不然,f\xe2\x82\x82因此更加专业化。