In Andrei\'s talk on GoingNative 2012 he talks about Variadic Templates, and he explains at one point by way of the example underneath how the parameter pack expansions work. B
1.
gun(A::hun(vs)...)
=> gun(A::hun(vs)...)
=> gun(A::hun(v1),
A::hun(v2),
…,
A::hun(vm))
2.
gun(A::hun(vs...))
=> gun(A::hun(vs...))
=> gun(A::hun(v1, v2, …, vm))
This should be obvious.
3.
gun(A::hun(vs)...)
=> gun(A::hun(v1), A::hun(v2), …, A::hun(vn))
(In this case the program won't compile if the lengths of Ts and vs differ)
The ...
will expand a pattern (which includes any parameter packs) preceding it, meaning that, in foo(Ts, Us, Vs)...
, each member of the list Ts
, Us
, Vs
(enumerated in lock step) will be substituted into that pattern, and a comma separated list will be formed:
foo(Ts, Us, Vs)...
=> foo(T1, U1, V1), foo(T2, U2, V2), …, foo(Tn, Un, Vn)
And if there are nested expansions, the innermost patterns will be expanded first. Therefore, in case 1, the pattern Ts
will first be expanded into T1, T2, …, Tn
. And then, the pattern preceding the outer ...
is A
— note that Ts
has been expanded — so it will be expanded to A
by substituting v1
, v2
, etc. into vs
.