#ifndef FOUR_H #define FOUR_H namespace four { 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;}; template struct Interface { typedef void FUN_R; 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) {} template typename enable_if_1::type f() { f_ ? f_(x_) : throw; } template typename enable_if_1::type g() { g_ ? g_(x_) : throw ; } 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; typedef Interface Interface; Interface i(&t2); i.f(); i.g(); } { Tst_1 t1; typedef Interface Interface; Interface i(&t1); i.f(); i.g(); } } } #endif