当前位置: 首页 > 知识库问答 >
问题:

可变参数模板未编译

牟波
2023-03-14
#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

共有2个答案

卞坚成
2023-03-14

使用折叠表达式的另一种解决方案如下所示:

#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;
}
濮赤岩
2023-03-14

函数等待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”。