Variadic模板示例不编译

时间:2016-04-07 22:42:02

标签: c++ templates c++11

我试图掌握并理解可变参数模板的概念。 我遇到了this示例

#include <iostream>
using namespace std;

//Output function to output any type without type specifiers like printf() family
template <typename T, typename ...P>
void output(T t, P ...p)
{
  cout << t << ' ';
  if (sizeof...(p)) { output(p...); }
  else { cout << '\n'; }
}

//Since variadic templates are recursive, must have a base case
void output() { cout << "\n"; }

//Test it
int main()
{
  //output();
  output('5', 2);

  return(0);
}

然而,当我尝试运行它时,我收到错误

main.cpp: In instantiation of 'void output(T, P ...) [with T = int; P = {}]':
main.cpp:10:29:   required from 'void output(T, P ...) [with T = char; P = {int}]'
main.cpp:21:16:   required from here
main.cpp:10:29: error: no matching function for call to 'output()'
   if (sizeof...(p)) { output(p...); }
                             ^
main.cpp:7:6: note: candidate: template<class T, class ... P> void output(T, P ...)
 void output(T t, P ...p)
      ^
main.cpp:7:6: note:   template argument deduction/substitution failed:
main.cpp:10:29: note:   candidate expects at least 1 argument, 0 provided
   if (sizeof...(p)) { output(p...); }
                             ^

有关如何修复它的任何建议。感谢

2 个答案:

答案 0 :(得分:2)

这比宣布订单更复杂。请参阅此答案:Switch passed type from template

template <typename T, typename ...P>
void output(T t, P ...p)
{
  cout << t << ' ';
  if (sizeof...(p)) { output(p...); } // HERE
  else { cout << '\n'; }
}

无论函数是否实际被调用,它都必须存在。您不能在函数中拥有一个虽然从未执行过但会导致语法错误的分支。因此,对sizeof...(p)的检查有点毫无意义。

所以为了让你的代码更清晰,因为它完全表达自己并且没有额外的东西,改为:

void output() { cout << "\n"; }

//Output function to output any type without type specifiers like printf() family
template <typename T, typename ...P>
void output(T t, P ...p)
{
  cout << t << ' ';
  output(p...);
}

您也不必按顺序定义它们,尽管它更容易。你可以这样做:

void output();

//Output function to output any type without type specifiers like printf() family
template <typename T, typename ...P>
void output(T t, P ...p)
{
  cout << t << ' ';
  output(p...);
}

void output() { cout << "\n"; }

甚至这个:

template <typename T, typename ...P>
void output(T t, P ...p)
{
  void output();
  cout << t << ' ';
  output(p...);
}

void output() { cout << "\n"; }

编辑:实际上,您可以避免使用0参数版本:

template < typename T >
void output(T t) { cout << t << "\n"; }

//Output function to output any type without type specifiers like printf() family
template <typename T, typename ...P>
void output(T t, P ...p)
{
  cout << t << ' ';
  output(p...);
}

答案 1 :(得分:1)

Name, Sex, Ethnicity, ClassA, ClassB, ClassC ExampleA, M, A, A, B, B ExampleB, M, C, B, B, A ExampleC, F, D, A, B, B ExampleD, F, A, A, B, B ExampleE, M, A, A, B, B 将成为第一个参数,其余为T t

P ...p

您将功能output('5', 2); // ^ 放在下面,而且

要解决此问题,您可以声明上面的函数,以便它可以看到:

void output()

或者在没有参数的情况下移动该函数:

void output();