#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;
}
当我编译时,我得到了这些错误:
In instantiation of 'void prints(A, B ...) [with A = int; B = {}]': error: no matching function for call to 'prints()' main.cpp:4:10: note: template argument deduction/substitution failed: main.cpp:7:11: note: candidate expects at least 1 argument, 0 provided
使用折叠表达式的另一种解决方案如下所示:
#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;
}
函数等待1个或多个参数:
template<typename A, typename... B>
void prints(A num, B... args)
当您仅使用1个参数调用它时,参数
包为空,因此递归调用:
prints(args...);
变成了
prints();
但函数等待(至少)1个参数,因此无法匹配此调用。
您需要添加
print()
的零参数重载以匹配空调用:
void prints()
{ }
您必须在递归版本之前声明它。
正如Evg所指出的(谢谢),从C 17开始,您可以避免零参数重载,并且使用if constexpr,您只能在参数
不为空。
那就是...从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 constrexr
)
if ( sizeof...(args) > 0u )
prints(args...);
您会得到一个编译错误(没有零参数重载),因为编译器必须编译打印(args…)
零件也当尺寸。。。(args)
为零(如果constexpr可以避免此情况,则正好是零)。
在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty
要解决的问题: 怎么创建一个拥有1个、2个或者更多的初始化器的类? 怎么避免创建一个实例而只拷贝部分的结果? 怎么创建一个元组? 最后的问题是关键所在:考虑一下元组!如果你能创建并且访问一般的元组,那么剩下的问题也将迎刃而解。 这里有一个例子(摘自“可变参数模板简述(A brief introduction to Variadic templates)”(参见参考)),要构建一个广义的、类型安全的
我努力一步一步地编写示例,使其清晰易懂。 此处显示的object BaseCreator公开了一个create函数,该函数使用一个内部类NewObject来分配一个t类型的新对象。new object类的默认方法是使用new运算符的常用方法,但是可以使用专门化来更改它,以使用不同的进程。我们稍后会看到它。 这很好,例如,假设我们有以下对象类型: 我们可以很容易地创建它们,例如: 我们还可以为特定对
我希望打印函数根据“值”的类型来做不同的事情。
受这个答案的启发,我生成了这段代码,其输出取决于编译器: 如果使用 GCC 11 编译,调用
我已经编写了一个具有递归评估的可变参数模板函数。对于最后一个参数,我在没有可变参数包的情况下实现了专业化,并且一切正常。 现在我想把可变函数参数转换成模板参数。 这是我的尝试: gcc和clang报告了一个模糊的过载,并且无法使用空参数包在“专业化”和“可变参数”之间做出决定。 我尝试删除特化并检查可变参数模板中的包大小,但是如果没有特化,编译器就无法推断出参数“p”。