1 c++ recursion templates variadic-templates
#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;
}
Run Code Online (Sandbox Code Playgroud)
当我编译时,我收到这些错误:
在实例化 'void prints(A, B ...) [with A = int; B = {}]':
错误:没有用于调用“prints()”的匹配函数
main.cpp:4:10: 注意:模板参数推导/替换失败:
main.cpp:7:11: 注意:候选人需要至少 1 个参数,0 提供
您的函数等待 1 个或多个参数:
template<typename A, typename... B>
void prints(A num, B... args)
Run Code Online (Sandbox Code Playgroud)
当您仅使用 1 个参数调用它时,args...包为空,因此递归调用:
prints(args...);
Run Code Online (Sandbox Code Playgroud)
变成
prints();
Run Code Online (Sandbox Code Playgroud)
但是您的函数等待(至少)1 个参数,因此无法匹配此调用。
您需要添加一个零参数重载prints()以匹配空调用:
void prints()
{ }
Run Code Online (Sandbox Code Playgroud)
并且您必须在递归版本之前声明它。
正如从 C++17 开始的 Evg(感谢)所指出的,您可以避免零参数重载,并且使用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...);
}
Run Code Online (Sandbox Code Playgroud)
并且您不再需要零参数重载。
请注意,如果您只是编写(使用简单的if, no if constexpr)
if ( sizeof...(args) > 0u )
prints(args...);
Run Code Online (Sandbox Code Playgroud)
你会得到(没有零参数重载)一个编译错误,因为编译器prints(args...)在sizeof...(args)为零时也必须编译该部分(正是if constexpr为了避免这种情况)。