template <typename T, typename ... Ts>
void foo(T , Ts ... )
{
}
template <typename ... Ts, typename T>
void bar(T , Ts ... )
{
}
int main()
{
foo<int, char>(1, 'c'); // well formed
foo(1, 'c');
// bar<int, char>(1, 'c'); // ill formed
bar(1, 'c');
}
为什么显式特化模板参数函数在第二种情况下不起作用(
bar
)?很明显,原因是参数包在参数列表中排在第一位,但仍然......为什么?
最终,这两种情况都可以通过隐式演绎来很好地工作。显式指定参数只会让编译器更容易。
对于将其标记为“重复”的人,我不是在谈论“正常参数”(如果存在类似的东西)。另外,我不是在问是否可以将参数包放置在参数表之前,而是在问为什么当包在参数列表中位于第一个位置时我无法显式指定模板参数。
Ts
然后显式指定模板参数为
int, char
时,参数包会吞噬所有指定的参数,i.e.,
Ts
是 int, char
和 T
尚未指定。 T
是从第一个参数的类型推导出来的,但这意味着 bar
的结果声明具有参数类型列表 int, int, char
,因为 int
是针对 T
推导出来的,但 int, char
是显式指定的对于Ts
。因此 bar
的这种特殊特化需要 3 个参数,但您只提供了 2 个。