正确方法:
可变参数模板与以下内容严格相关induction
,一个数学概念。
编译器解析以下函数调用
print('a', 3, 4.0f);
into
std::cout<< 'a' <<std::endl;
print(3, 4.0f);
被解析为
std::cout<< 'a' <<std::endl;
std::cout<< 3 <<std::endl;
print( 4.0f);
被解析为
std::cout<< 'a' <<std::endl;
std::cout<< 3 <<std::endl;
std::cout<< 4.0f <<std::endl;
print();
此时,它会搜索与空函数匹配的函数重载。
- 所有具有 1 个或多个参数的函数都与可变参数模板匹配
- 所有没有参数的函数都与空函数匹配
罪魁祸首是,对于每种可能的参数组合,您必须只有 1 个函数。
ERROR 1:
执行以下操作将会出错
template< typename T>
void print( const T& arg) // first version
{
cout<< arg<<endl;
}
template <typename T, typename... Types>
void print (const T& firstArg, const Types&... args) // second version
{
cout << firstArg << endl; // print first argument
print(args...); // call print() for remaining arguments
}
因为当你打电话时print
编译器不知道要调用哪个函数。
Does print(3)
指的是“第一”还是“第二”版本?两者都是有效的,因为第一个有 1 个参数,第二个也可以接受一个参数。
print(3); // error, ambiguous, which one you want to call, the 1st or the 2nd?
ERROR 2:
无论如何,以下内容都会出错
// No empty function
template <typename T, typename... Types>
void print (const T& firstArg, const Types&... args)
{
cout << firstArg << endl; // print first argument
print(args...); // call print() for remaining arguments
}
事实上,如果你单独使用它而不需要编译器就可以
print('k', 0, 6.5);
被解析为
std::cout<<'k'<<std::endl;
print(0, 6.5);
被解析为
std::cout<<'k'<<std::endl;
std::cout<< 0 <<std::endl;
print( 6.5);
被解析为
std::cout<<'k'<<std::endl;
std::cout<< 0 <<std::endl;
std::cout<< 6.5 <<std::endl;
print(); //Oops error, no function 'print' to call with no arguments
正如您在最后一次尝试中看到的,编译器尝试调用print()
没有争论。但是,如果这样的函数不存在,则不会调用它,这就是为什么您应该提供该空函数(不用担心,编译器将优化代码,因此空函数不会降低性能)。