Template Magic
All remember compile-time factorial example
#include <iostream> template<const int N> struct factorial { int num; factorial() { num = N * factorial<N-1>().num; } }; template<> struct factorial<0> { const int num = 1; }; int main() { factorial<5> t; std::cout << t.num << "\n"; return 0; }
Now we can use variadic template args like this
#include <iostream> template<const int ...Args> struct factorial; struct base { int num = 1; }; template<const int N, const int ...Args> struct factorial<N, Args...> : base { factorial() { num = N * factorial<Args...>().num; } }; template<> struct factorial<> : base { }; int main() { factorial<1,2,3,4,5> t; std::cout << t.num << "\n"; return 0; }
Moreover we could do better with inheritance
#include <iostream> template<const int ...Args> struct factorial { const int num = 1; }; template<const int N, const int ...Args> struct factorial<N, Args...> : factorial<Args...> { typedef factorial<Args...> base_t; const int num = N * base_t::num; }; template<> struct factorial<> { const int num = 1; }; int main() { factorial<1,2,3,4> t; std::cout << t.num << "\n"; return 0; }
Recursion via method run(). Conclusion in class with one template argument
#include <iostream> #include <string> template< typename ...ARGS > struct record; template <typename FIELD, typename ...ARGS> struct record< FIELD, ARGS... > : record<ARGS...> { typedef record<ARGS...> base_record_t; enum { index = base_record_t::index + 1 }; void run() { base_record_t::run(); std::cout << FIELD::name() << " " << index << "\n"; } }; template <typename FIELD> struct record<FIELD> { enum { index = 0 }; void run() { std::cout << FIELD::name() << " " << index << "\n"; } }; struct f1 { static const char * name() { return "f1"; } }; struct f2 { static const char * name() { return "f2"; } }; struct f3 { static const char * name() { return "f3"; } }; int main() { record<f1,f2,f3> r; r.run(); return 0; }