This question already has an answer here:
What is the difference between the following 3 calls for gun
function?
template <class... Ts> void fun(Ts... vs) {
gun(A<Ts...>::hun(vs)...);
gun(A<Ts...>::hun(vs...));
gun(A<Ts>::hun(vs)...);
}
I am interested in an answer that explains the three calls using a specific example.
Originally I just literally answered the question, but I wanted to expand this somewhat to provide a more thorough explanation of how what packs are expanded into what. This is how I think about things anyway.
Any pack immediately followed by an ellipses is just expanded in place. So
A<Ts...>
is equivalent toA<T1, T2, ..., TN>
andhun(vs...)
is similarly equivalent tohun(v1, v2, ..., vn)
. Where it gets complicated is when rather than a pack followed by ellipses you get something like((expr)...)
. This will get expanded into(expr1, expr2, ..., exprN)
whereexpri
refers to the original expression with any pack replaced with thei
th version of it. So if you hadhun((vs+1)...)
, that becomeshun(v1+1, v2+1, ..., vn+1)
. Where it gets more fun is thatexpr
can contain more than one pack (as long as they all have the same size!). This is how we implement the standard perfect forwarding model;Here
expr
contains two packs (Args
andargs
are both packs) and the expansion "iterates" over both:That reasoning should make it possible to quickly walk through your cases for, say, what happens when you call
foo(1, 2, '3')
.The first one,
gun(A<Ts...>::hun(vs)...);
expandsTs
"in place" and then there's an expression to expand for the last ellipses, so this calls:The second one,
gun(A<Ts...>::hun(vs...));
expands both packs in place:The third one,
gun(A<Ts>::hun(vs)...)
, expands both packs at the same time:[update] For completeness,
gun(A<Ts>::hun(vs...)...)
would call:Finally, there's one last case to consider where we go overboard on the ellipses:
This will not compile. We expand both
Ts
andvs
"in place", but then we don't have any packs left to expand for the final ellipses.Here's how they expand when Ts is T, U and vs is t, u:
And one more case you didn't cover:
If you run the code below in VS14 you'll get this output:
Code: