Variadic模板未编译

Variadic template not compiling

本文关键字:编译 Variadic      更新时间:2023-10-16
#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;
}