Home > Software engineering >  How C expands multiple parameters packs simultaneously,
How C expands multiple parameters packs simultaneously,

Time:09-19

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.

  • Related