Having following functions f0
, f1
, f2
in C 14 code, which accepts arbitrary number of fixed-length arrays:
#include <functional>
template<typename... TS, size_t N> void f0( TS(&& ... args)[N] ) {}
template<typename T, size_t... NS> void f1( T(&& ... args)[NS] ) {}
template<typename... TS, size_t... NS> void f2( TS(&& ... args)[NS] ) {}
int main(){
f0({1,2}, {3.0,4.0}, {true, false});
f1({1,2,3}, {4,5}, {6});
f2({1,2,3}, {4.0,5.0}, {true});
return 0;
}
Function f0
accepts arrays with different types and fixed array length. Function f1
accepts arrays with fixed type and different array lengths. It's clear how this works: C compiler deduces variable-length parameter pack in immediate context of template function instantiation, which is expanded in (&& ... args)
expression.
Function f2
accepts arrays with different types and different array lengths, which produces two variable-length parameter packs, however there is only one ellipsis operator in pack expansion (&& ... args)
, but code compiles and works well.
So question is: what is general rule for expanding multiple parameter packs within single ellipsis operator? Obviously, at a minimum, they must be the same length, but what are the other requirements? Is there a precise definition that the n-th element of the first parameter packing should expand along with the n-th element of the second parameter packing?
Also, following code with explicit template argument provision does not compile: f2<int,float,bool,3,2,1>({1,2,3},{4.0f,5.0f},{true});
. It would be interesting to know the reasons for this behaviour.
CodePudding user response:
All packs appearing as part of one pack expansion (...
) must have exactly the same length. Otherwise substitution fails (which depending on context is a hard error or SFINAE). (see [temp.variadic]/7)
All packs are expanded so that the i-th expanded element of the pack expansion uses the i-th element of each pack. For the detailed expansion rule see [temp.variadic]/8.
(Links are to the post-C 20 draft of the standard, but the same applies to C 14.)
CodePudding user response:
A template parameter pack is a template parameter that accepts zero or more template arguments (non-types, types, or templates). A function parameter pack is a function parameter that accepts zero or more function arguments.
A template with at least one parameter pack is called a variadic template.
Visit[1]: https://en.cppreference.com/w/cpp/language/parameter_pack
Visit[2]: Multiple expansions of multiple parameter packs in the same expression
Visit[3]: https://www.ibm.com/docs/en/zos/2.1.0?topic=only-variadic-templates-c11
I hope this help you.