我会简化和缩短这个问题以便于回答。
必要的是:
为什么要编译和执行此代码
# include <iostream>
template <class A> class Goofy {};
template <int N, template <class> class B, class A, int ... K, class ... Z>
void f ( A a, B<A> b, Z ... z )
{
std::cout << "I'm executed" << std::endl;
}
int main()
{
Goofy<int> goofy;
f<1, Goofy, int, 2, 3, 4>(2,goofy,1.3,'a',1.f);
}
而以下不是?
# include <iostream>
template <class A> class Goofy {};
template <int N, template <class> class B, class A, int ... K, class ... Z>
void f ( A a, B<A> b, Z ... z )
{
std::cout << "I'm executed" << std::endl;
}
int main()
{
Goofy<int> goofy;
f<1, Goofy, int, 2, 3, 4, double, char, float>(2,goofy,1.3,'a',1.f);
}
唯一的区别是类型的显式和一致供应
实例化包Z
。
我不认为这会以编译错误结束,而且还会 ,恕我直言,诊断告诉模板扣除/替换失败 没有必要扣除。
有人可以向我解释一下吗?
我使用编译器GNU 7.3.1和 clang 4.0.1并且两者都表现相同,所以我担心我的推理中存在严重错误......但我找不到。
答案 0 :(得分:3)
您的代码可以缩减为:
template <int... N, class T>
auto foo(T) {};
auto test()
{
foo<1, 2, 3>(4); // OK
foo<1, 2, 3, int>(4); // ERROR
}
原因是可变参数是贪婪的。这就是为什么他们在明确说明它们时需要最后的原因。
撰写foo<1, 2, 3>(4);
时:
1, 2, 3
与int... N
匹配 - &gt; N
推断为1, 2, 3
- &gt;确定T
从函数参数推导出来,即4
到int
- &gt;行撰写foo<1, 2, 3, int>(4);
时:
1, 2, 3, int
与int... N
匹配 - &gt;错误