#ifndef FIVE_H #define FIVE_H namespace five { enum FUN {FUN_F = 1, FUN_G = 4}; struct Tst_2 { const static int enabled_fun = FUN_F | FUN_G; void f() { std::cout << "f" << std::endl; } void g() { std::cout << "g" << std::endl; } }; struct Tst_1 { const static int enabled_fun = FUN_F ; void f() { std::cout << "f" << std::endl; } }; template struct enable_if_1 {typedef T type;}; template < class T> struct enable_if_1<0, T > {}; template struct Int2Type {typedef T type;}; template struct Int2Type<0, T> {typedef void type;}; struct Interface { template Interface(T* x) : x_(x), f_(0), g_(0) { set_g( (typename Int2Type::type*)0); set_f( (typename Int2Type::type*)0); } template void set_f (T* p = 0) { f_ = (vTable_::template f); } void set_f (void* v =0) {} template void set_g (T* p = 0) { g_ = (vTable_::template g); } void set_g (void* v =0) {} void f() { if (f_) f_(x_); } void g() { if (g_) g_(x_) ; } private: template struct vTable_ { template static typename enable_if_1::type f(void* x) { static_cast(x)->f(); } template static typename enable_if_1::type g(void* x) { static_cast(x)->g(); } }; private: typedef void (*FUN)(void*); FUN f_, g_; void* x_; }; void test() { { Tst_2 t2; Interface i(&t2); i.f(); i.g(); } { Tst_1 t1; Interface i(&t1); i.f(); i.g(); } } } #endif