Document directory
- Variadic templates)
- C ++ code
Variadic templates)
Before C ++ 0x, the number and type of parameters in the template (including class templates and function templates) are fixed and must be pre-defined. In C ++ 0x, this is improved. Templates (both Class templates and function templates) can specify any number of parameters of any type, this is the so-called variable length parameter template (variadic templates ).
The following code describes the function templates with variable length parameters.
C ++ code
#include <iostream>using namespace std;template<typename T>void output(T&& value){ cout << value << endl;}template<typename First, typename... Rest>void output(First&& first, Rest&&... rest){ cout << first << ","; output(forward<Rest>(rest)...);}template<typename T>T sum(T&& value){ return value;}template<typename First, typename Second, typename... Rest>First sum(First&& first, Second&& second, Rest&&... rest){ return sum(first + second, forward<Rest>(rest)...);}int main(){ double d = 2.3; output(42,"hello",d,'a'); output("hello",d,'a'); output(d,'a'); output('a'); output(sum(1), sum(1, 2), sum(1, 2, 3)); return 0;}//42,hello,2.3,a//hello,2.3,a//2.3,a//a//1,3,6Code Description
- The output and sum in the Code are two function templates that can accept variable length parameters.
The output function accepts one or more parameters. The function outputs the values of each parameter.
The sum function also accepts one or more parameters. The function is used to calculate the sum of parameters.
- The output function has two versions in the code.
- When there is only one parameter, call 4 ~ Non-recursive versions defined in line 8,
The number of parameters in this version is fixed. It is valid before C ++ 11.
- When there are two or more parameters, call ~ The recursive version defined in line 14,
The number of parameters in this version is variable, depending on the new language features in C ++ 11.
- The typename... rest section in the template parameter list in code 9th is called the template parameter package.
In actual calls, the template parameter package rest will store the types of variable length parameters (all parameters after the first parameter ).
For example, output (42, "hello", D, 'A') is used for Row 3. The rest content is (char *, double &, char)
- The rest &... rest section in the function parameter list in code 10th is called the function parameter package.
In actual calls, the function parameter package rest will store the values of the variable length parameters (all parameters after the first parameter ).
For example, output (42, "hello", D, 'A') is used in Row 3. The rest content is ("hello", D, 'A ')
- In line 2 of the Code,... is called the unpackage operator,
In actual calls, the unwrapped operator uses the previous expression (namely, forward <rest> (rest) as the template to expand
Template parameter package rest and function parameter package rest. After expansion, the generated expressions are connected by commas,
For example, output (42, "hello", D, 'A') is used in Row 3. When calling, forward <rest> (rest)... is expanded
Forward <char *> ("hello"), forward <double &> (D), forward <char> ('A ')
- According to the above analysis
The output function of the recursive version outputs the value of the first parameter, and uses the remaining parameters to call itself recursively after the comma,
The output function of a non-recursive version only outputs the value of the unique parameter value, and does not output a comma.
- Output (42, "hello", D, 'A') is used in Row 3. The simulated running result is as follows:
Output (42, "hello", D, 'A ')
= Output "42," then call output (Forward <char *> ("hello"), forward <double &> (D), forward <char> ('A '))
= Output "42," Call output ("hello", D, 'A ')
= Output "42, hello," and then call output (Forward <double &> (D), forward <char> ('A '))
= Output "42, hello," and then call output (D, 'A ')
= Output "42, hello, 2.3," and then call output (Forward <char> ('A '))
= Output "42, hello, 2.3," and then call output ('A ')
= Output "42, hello, 2.3, a"
Note that the non-recursive version is called in the last step, so no comma is output.
- Similar to the output function, the sum function has two versions.
Repeat the above analysis to see
The sum function of the recursive version calculates the sum of the first and second parameters and uses the calculation result and the remaining parameters to call itself recursively,
The non-recursive sum function returns the value of the unique parameter value.
- The second line uses sum (34th, 3). The simulated running result is as follows:
Sum (1, 2, 3)
= Sum (1 + 2, forward <int> (3 ))
= Sum (1 + 2, 3)
= Sum (1 + 2 + 3)
= 1 + 2 + 3
= 6