Variadic模板未编译
Variadic template not compiling
#include <iostream>
template<typename A, typename... B>
void prints(A num, B... args){
std::cout << num << std::endl;
prints(args...);
}
int main(){
prints(1,2,3);
return 0;
}
当我编译时,我会得到以下错误:
在"void prints(A,B…([with A=int;B={}]"的实例化中:错误:对"prints(("的调用没有匹配的函数main.cpp:4:10:注意:模板参数推导/替换失败:main.cpp:7:11:注意:候选者需要至少1个参数,0提供
您的函数等待一个或多个参数:
template<typename A, typename... B>
void prints(A num, B... args)
当您只使用1个参数调用它时,args...
包是空的,因此递归调用:
prints(args...);
成为
prints();
但是您的函数等待(至少(1个参数,因此无法匹配此调用。
您需要添加prints()
的零参数重载来匹配空调用:
void prints()
{ }
并且您必须在递归版本之前声明它。
正如Evg所指出的(谢谢(,从C++17开始,您可以避免零参数重载,并且使用if constexpr
,您只能在args...
不为空时调用递归。
也就是说…从C++17开始,您可以编写
template <typename A, typename... B>
void prints (A num, B... args) {
std::cout << num << std::endl;
if constexpr ( sizeof...(args) > 0u )
prints(args...);
}
并且您不再需要零参数重载。
注意,如果你只是写(用一个简单的if
,没有if constexpr
(
if ( sizeof...(args) > 0u )
prints(args...);
您会得到(没有零参数重载(编译错误,因为当sizeof...(args)
为零时,编译器也必须编译prints(args...)
部分(正是if constexpr
避免了这种情况(。
使用折叠表达式的另一个解决方案如下所示:
#include <iostream>
#include <utility>
template <class... TArgs>
void prints(TArgs&&... args) {
(std::cout << ... << std::forward<TArgs>(args));
}
int main(){
prints(1,2,3);
return 0;
}