Andrei Alexandrescu gave an excellent talk entitled: Variadic Templates are Funadic.
He presents the following 3 expansions which are subltey different:
#include
#include
#include
#include
#include
template
std::unique_ptr
type_name()
{
return std::unique_ptr
(
__cxxabiv1::__cxa_demangle(typeid(T).name(), nullptr,
nullptr, nullptr),
std::free
);
}
void display() {}
template
void
display()
{
std::cout << type_name().get() << ' ';
}
template
void
display()
{
std::cout << type_name().get() << ' ';
display();
}
template
struct A
{
template
static
int
hun(Us... us)
{
std::cout << "A<";
display();
std::cout << ">::hun(";
display();
std::cout << ")\n";
return 0;
}
};
template
void gun(T...) {}
template void fun( Ts... vs )
{
std::cout << "gun( A::hun(vs)...);\n";
gun( A::hun(vs)...);
std::cout << "\ngun( A::hun(vs...));\n";
gun( A::hun(vs...));
std::cout << "\ngun( A::hun(vs)...);\n";
gun( A::hun(vs)...);
}
int main()
{
fun(1, 'a', 2.3);
}
Output:
gun( A::hun(vs)...);
A::hun(int )
A::hun(char )
A::hun(double )
gun( A::hun(vs...));
A::hun(int char double )
gun( A::hun(vs)...);
A::hun(int )
A::hun(char )
A::hun(double )