1. Overview
The new feature of c++11-the variable template parameter (variadic templates) is one of the most powerful features of C++11, which is highly generalized for parameters that represent 0 to any number of parameters of any type. Compared to c++98/03, the class template and function template can only contain a fixed number of template parameters, variable template parameters is undoubtedly a huge improvement. However, due to the fact that the variable template parameters are abstract, it is necessary to use some skills, so it is one of the most difficult to understand and master in C++11.
Although it is difficult to master the variable template parameters, but it is one of the most interesting features of C++11, this article hopes to lead readers to understand and master this feature, and also through some examples to demonstrate the use of variable parameter template.
2. Expansion of variable template parameters
The semantics of the variadic template and the Normal template are the same, except that the wording is slightly different, and the variable parameter template needs to be appended with the ellipsis "..." after the TypeName or class. For example, we often declare a variable template parameter:template<typename...> or template<class...> the definition of a typical variable template parameter is this:
Template<typename ... t> void Fun (T ... args) {}
In the definition of the above variable template parameter, the ellipsis has a function of two:
1. Declare a parameter package T ... args, which can contain 0 to any of the template parameters;
2. On the right side of the template definition, the parameter package can be expanded into a single parameter.
The above parameter, args, is preceded by an ellipsis, so it is a variable template parameter, and we refer to the parameter with the ellipsis as a "parameter Packet", which contains 0 to N (n>=0) template parameters. We can not directly get the parameter package args in each parameter, only by expanding the parameter package to get each parameter in the parameter package, which is a key feature of the use of variable template parameters, but also the biggest difficulty, that is, how to expand the variable template parameters.
The variable template parameters and the Normal template parameter semantics are consistent, so it can be applied to functions and classes, variable template parameter functions and variable template parameter classes, however, the template function does not support the partial localization, so the variable template parameter functions and variable template parameter classes expand variable template parameters are not the same method, Let's take a look at their methods of expanding the variable template parameters separately.
3. Variable template parametric functions
A simple variable template parameter function:
Template<typename ... t>void fun (T ... args) { // number of print parameters sizeof... (args) << Endl; }
In the above example, fun () does not pass in parameters, so the parameter package is empty, the output size is 0, the subsequent two calls are passed in two and three parameters respectively, so the output size is 2 and 3. Since the type and number of variable template parameters are not fixed, we can pass any type and number of arguments to the function f. This example simply prints out the number of variable template parameters, and if we need to print out each parameter in the parameter pack, we need to pass some methods. There are two ways to expand a variable-template parametric function: One is to expand the parameter package by using a recursive function, and the other is to expand the parameter package by using a comma-expression. Let's take a look at how to expand the parameter pack using both of these methods.
3.1 to expand a parameter package as a recursive function
To expand a parameter package with a recursive function, you need to provide a function for the expansion of a parameter pack and a recursive termination function, which is used to terminate the recursion, to see the following example.
#include <iostream>using namespacestd;//Final recursive functionvoidprint () {cout<<"Empty"<<Endl; }//Expand FunctionTemplate <typename T, TypeName ... Args>voidPrint (T head, args ... args) {cout<< Head <<","; Print (args ...); }intMain () {print (1,2,3,4); return 0; }
The previous meeting outputs each parameter until empty. The function that expands the parameter package has two, one is recursive function, the other is recursive terminating function, parameter package args ... Recursively calls itself during the unfolding process, with fewer parameters per call to the parameter pack, until all parameters are expanded, and when no arguments are called, the non-template function print terminates the recursive process.
The procedure for recursive invocation is this:
Print (1,2,3,4);p rint (2,3,4);p rint (3,4);p rint (4);p rint ();
The recursive termination function above can also be written like this:
Template <class t>void print (T t) { cout << t << Endl;}
After modifying the recursive termination function, the invocation procedure in the previous example is this:
Print (1,2,3,4);p rint (2,3,4);p rint (3,4);p rint (4);
When the parameter package expands to the last parameter, the recursion is reached.
We'll explain other ways to use variadic templates in the next blog.
c++11 use of variable parameter templates 1