c++ - Variadic Templates - different types of expansion -
andrei alexandrescu gave excellent talk entitled: variadic templates funadic.
he presents following 3 expansions subltey different:
template <class... ts> void fun( ts... vs ) { gun( a<ts...>::hun(vs)...); gun( a<ts...>::hun(vs...)); gun( a<ts>::hun(vs)...); }
he explains:
call 1: expands ts
instatiation of class a
, calls hun(vs)
expands parameters again when passing them gun
call 2: expands ts
, vs
separately
call 3: expnads in lock step, ie: expand argument 1 of ts
, argument 1 of vs
expand argument 2 of ts
, argument 2 of vs
expand argument n of ts
, argument n of vs
other discussion on variadic templates seem cover simple variadic class templates , variadic functions such typesafe printf etc. unsure how these different types of expansion effect code , each type useful.
does have examples demonstrate application of each type of expansion?
#include <iostream> #include <memory> #include <typeinfo> #include <cstdlib> #include <cxxabi.h> template <typename t> std::unique_ptr<char, void(*)(void*)> type_name() { return std::unique_ptr<char, void(*)(void*)> ( __cxxabiv1::__cxa_demangle(typeid(t).name(), nullptr, nullptr, nullptr), std::free ); } void display() {} template <class t> void display() { std::cout << type_name<t>().get() << ' '; } template <class t, class t2, class ...tail> void display() { std::cout << type_name<t>().get() << ' '; display<t2, tail...>(); } template <class... ts> struct { template <class... us> static int hun(us... us) { std::cout << "a<"; display<ts...>(); std::cout << ">::hun("; display<us...>(); std::cout << ")\n"; return 0; } }; template <class ...t> void gun(t...) {} template <class... ts> void fun( ts... vs ) { std::cout << "gun( a<ts...>::hun(vs)...);\n"; gun( a<ts...>::hun(vs)...); std::cout << "\ngun( a<ts...>::hun(vs...));\n"; gun( a<ts...>::hun(vs...)); std::cout << "\ngun( a<ts>::hun(vs)...);\n"; gun( a<ts>::hun(vs)...); } int main() { fun(1, 'a', 2.3); }
output:
gun( a<ts...>::hun(vs)...); a<int char double >::hun(int ) a<int char double >::hun(char ) a<int char double >::hun(double ) gun( a<ts...>::hun(vs...)); a<int char double >::hun(int char double ) gun( a<ts>::hun(vs)...); a<int >::hun(int ) a<char >::hun(char ) a<double >::hun(double )
Comments
Post a Comment