I am trying to understand the following code:
template <class...Ts, class...Us> void f(void) {};
int main() {
f<int, char, float, double>();
}
I don't know how template argument deduction deduces Ts and Us. In this answer, I learned that parameter packs are greedy, so Ts will match all specified arguments: [ Ts = int, char, float, double ]. But what about Us: it has not been deduced yet? or what happens in this case?
I expect that the compiler throws a deduction error since it cannot figure out what Us is expanded to.
Can I somehow, in the template argument-list, tell the compiler that I need Ts to be int, char, and Us to be float, double? how I can do that? I mean, can the call expression be something like that:
f<{int, char}, {float, double}>();
I found out that when I edit the above code to be as follows, this will fit my needs:
template <class...> struct S{};
template <class...Ts, class...Us> void g(S<Ts...>, S<Us...>)
{
};
int main() {
S<int, char> s1;
S<float, double> s2;
g(s1 ,s2);
}
But I still need to understand why in this case Ts is [int, char], and Us is [float, double].
What I think in this case is that: Since parameter packs are greedy, template argument deduction deduces Ts as [S<int, char>, S<float, double>] and Us is left off un-deduced or just empty. Right?
This makes me think that
First,
[int, char]gets substituted in the place ofTs...in the first function parameterS<Ts..>, so it gets expanded intoS<int, char>. Then[float, double]gets substituted in the place ofUs...in the second function parameterS<Us..>, so it gets expanded intoS<float, double>.Second, template argument deduction deduces
Tsas[int, char]andUsas[float, double].
Is my understanding correct in this case?