can't understand variadic templates in c++

假装没事ソ 提交于 2019-12-05 09:54:42

A variadic expression can capture 0 arguments or more.

Take for example the call print(1). Then T captures int and Types = {} - it captures no arguments. Thus the call print(args...); expands to print();, which is why you need a base case.


You don't need the recursion at all. I always use the following debuglog function in my code (modified for your needs):

template<typename F, typename ... Args>
  void
  print(const F& first, const Args&... args) // At least one argument
  {
    std::cout << first << std::endl;
    int sink[] =
      { 0, ((void)(std::cout << args << std::endl), 0)... };
    (void) sink;
  }

Because this variadic function takes at least one argument, you are free to use print(void) for whatever you like now.

It is recursive because the variadic part of the template is reduced each call, for example a call would recursively look like this

print(1, 2, 3, 4, 5)  // firstArg == 1
                      // ...args == 2,3,4,5

print(2, 3, 4, 5)     // firstArg == 2
                      // ...args == 3,4,5

print(3, 4, 5)        // firstArg == 3
                      // ...args == 4,5

print(4, 5)           // firstArg == 4
                      // ...args == 5

print(5)              // firstArg == 5
                      // ...args == {}

print()

The print() is necessary as a base case for when the variadic list is empty.

Consider a call to the template function with a single argument.

print(1);

firstArg would bind to the 1 (T = int), and Types... would bind to nothing. A variadic argument pack is zero or more arguments.

Thus, in this call:

print(args...);

args... is an empty parameter pack. So it expands into:

print();

Since your function template matches any call to print with one or more arguments, you need a separate function to handle zero arguments. Which in this case is the trivial function:

void print () { }

Assume the following code:

int a, b, c;
print(a, b, c);

The compiler will implicitly create the following code:

print(const int& firstArg)
{
    std::cout << firstArg << std::endl; // print first argument
    print(); // call print() for remaining arguments
}

print(const int& firstArg, const int& arg2)
{
    std::cout << firstArg << std::endl; // print first argument
    print(arg2); // call print() for remaining arguments
}

print(const int& firstArg, const int& arg2, const int& arg3)
{
    std::cout << firstArg << std::endl; // print first argument
    print(arg2, arg3); // call print() for remaining arguments
}

as you can see in the version with only one argument, the compiler will call a "print" method with no arguments. Since the variadic print function ALWAYS requires at least one parameter this will not match...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!