Here's how they expand when Ts is T, U and vs is t, u:
gun(A::hun(vs)...) -> gun(A::hun(t), A::hun(u))
gun(A::hun(vs...)) -> gun(A::hun(t, u));
gun(A::hun(vs)...) -> gun(A::hun(t), A::hun(u))
And one more case you didn't cover:
gun(A::hun(vs...)...) -> gun(A::hun(t, u), A::hun(t, u))
If you run the code below in VS14 you'll get this output:
calling gun(A::hun(vs)...);
struct A::hun(double);
struct A::hun(int);
gun(struct A, struct A);
calling gun(A::hun(vs...));
struct A::hun(int, double);
gun(struct A);
calling gun(A::hun(vs)...);
struct A::hun(double);
struct A::hun(int);
gun(struct A, struct A);
calling gun(A::hun(vs...)...);
struct A::hun(int, double);
struct A::hun(int, double);
gun(struct A, struct A);
Code:
#include
#include
using namespace std;
void printTypes() {}
template void printTypes(T, Ts... vs) {
cout << typeid(T).name() << (sizeof...(Ts) ? ", " : "");
printTypes(vs...);
}
template struct A {
template
static auto hun(Us... vs) {
cout << " " << typeid(A).name() << "::hun(";
printTypes(vs...);
cout << ");" << endl;
return A{};
}
};
template void gun(Ts... vs) {
cout << " gun(";
printTypes(vs...);
cout << ");" << endl;
}
template void fun(Ts... vs) {
cout << "calling gun(A::hun(vs)...);" << endl;
gun(A::hun(vs)...);
cout << "calling gun(A::hun(vs...));" << endl;
gun(A::hun(vs...));
cout << "calling gun(A::hun(vs)...);" << endl;
gun(A::hun(vs)...);
cout << "calling gun(A::hun(vs...)...);" << endl;
gun(A::hun(vs...)...);
}
int main() {
fun(1, 2.0);
}