很明显,下面的代码可以编译并运行。
template<typename ...Args>
void func (Args... args) { }
func(1,2,3,4,5); // succeed
template<typename T, typename ...Args>
void func (T arg_1, Args... args) { }
func(1,2,3,4,5); //succeed
但是如果我分离出一个模板参数T
而不使用它,它将无法编译。
template<typename T, typename ...Args>
void func (Args... args) { }
func(1,2,3,4,5); // can't compile
c++抛出错误:
main.cpp: In function ‘int main()’:
main.cpp:33:20: error: no matching function for call to ‘func(int, int, int, int, int)’
33 | func(1, 2, 3, 4, 5);
| ^
main.cpp:26:6: note: candidate: ‘template<class T, class ... Args> void func(Args ...)’
26 | void func (Args... args)
| ^~~~
main.cpp:26:6: note: template argument deduction/substitution failed:
main.cpp:33:20: note: couldn’t deduce template parameter ‘T’
33 | func(1, 2, 3, 4, 5);
如果在使用
时显式指定了第一个模板形参,也可以进行编译:template<typename T, typename ...Args>
void func (Args... args) { }
func<int>(1, 2, 3, 4, 5); //succeed
为什么必须显式指定参数或使用它?
虽然没有人会这样做,但我只是想知道编译器是如何扣除参数的。
实例化模板需要指定或推导其所有参数。这是一条基本规则,没有例外或变通方法。
有很多模板不使用任何参数,比如。std::integer_sequence
。模板形参即使在模板本身中没有被引用,也有一定的作用。