Issue
This Content is from Stack Overflow. Question asked by Vladislav Ihost
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.
Solution
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.)
This Question was asked in StackOverflow by Vladislav Ihost and Answered by user17732522 It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.