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;
}
Комментариев нет:
Отправить комментарий