Cannot understand variational patterns in C ++

I read about variable templates, and I came across this example. The book mentions that the print() function is used to complete the recursion process. I really do not understand its use. Why does the author use this empty print() function?

 void print () // can't get why this function is used { } template <typename T, typename... Types> void print (const T& firstArg, const Types&... args) { std::cout << firstArg << std::endl; // print first argument print(args...); // call print() for remaining arguments } 
+5
source share
4 answers

In a variational expression, 0 arguments or more can be written.

Take for example the call to print(1) . Then T captures int and Types = {} - it does not commit any arguments. So calling print(args...); expands to print(); , so you need a basic case.


You don't need 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; } 

Since this variational function takes at least one argument, you can use print(void) for what you like now.

+7
source

This is recursive, because the variational part of the template is reduced every call, for example, the call will 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() 

print() needed as a base case when the variable list is empty.

+3
source

Consider calling a template function with a single argument.

 print(1); 

firstArg will bind to 1 ( T = int ), and Types... will not bind to anything. The Variadic argument parameter contains zero or more arguments.

So in this call:

 print(args...); 

args... is an empty parameter package. Thus, it expands:

 print(); 

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

 void print () { } 
+3
source

Assume the following code:

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

The compiler will implicitly generate 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 the print method with no arguments. Since the ALWAYS variable print function requires at least one parameter, this will not match ...

+3
source

All Articles