I saw this example on cppreference.com. I am not clear on the pack expansion of the function arguments.
Function parameter list
In a function parameter list, if an ellipsis appears in a parameter declaration (whether it names a function parameter pack (as in, Args ... args) or not) the parameter declaration is the pattern:
template<typename ...Ts> void f(Ts...) {} f('a', 1); // Ts... expands to void f(char, int) f(0.1); // Ts... expands to void f(double) template<typename ...Ts, int... N> void g(Ts (&...)[N]) {} int n[1]; g<const char, int>("a", n); // Ts (&...)[N] expands to const char (&)[2], int(&)[1]
Note: in this pattern, the ellipsis is the innermost element, not the last element as in all other pack expansions.
Pack expansion A pattern followed by an ellipsis, in which the name of at least one parameter pack appears at least once, is expanded into zero or more comma-separated instantiations of the pattern, where the name of the parameter pack is replaced by each of the elements from the pack, in order. template<class...
With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration.
Parameter packs (C++11) A parameter pack can be a type of parameter for templates. Unlike previous parameters, which can only bind to a single argument, a parameter pack can pack multiple parameters into a single parameter by placing an ellipsis to the left of the parameter name.
This works:
template<typename ...Ts, int... N> void g(Ts (&...array)[N]) {}
int n[1];
g<const char, int>("a", n); // Ts (&...)[N] expands to const char (&)[2], int(&)[1]
but apparently many compilers have a problem if you skip the name array
. I don't know if this is a quirk of the compilers or of the standard (both are reasonable: this is a serious bit of corner-case syntax).
As noted by @Xeo, a less obtuse way to deal with the declaration syntax of C is to cheat our way around the issue:
template<typename T> using Type = T;
template<typename... Ts, int... N> void g( Type<Ts[N]>&... ) {}
is easier to parse and removes the need for (at least some) compilers to have a variable name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With