#ifndef TWO_H #define TWO_H namespace two { 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 Int2Type {}; struct Interface { template Interface(T* x) : x_(x), f_(vTable_::f), g_(vTable_::g) {} void f() { f_(x_); } void g() { g_(x_); } private: template struct vTable_ { static void f(void* x) { ff(x, (Int2Type< TT::enabled_fun & FUN_F>*)0); } template static void ff(void* x, Int2Type* d ) { static_cast(x)->f(); } static void ff(void* x, Int2Type<0>* d ) { throw FUN_F;} static void g(void* x) { gg(x, (Int2Type< TT::enabled_fun & FUN_G>*)0); } template static void gg(void* x, Int2Type* d ) { static_cast(x)->g(); } static void gg(void* x, Int2Type<0>* d ) { throw FUN_G;} }; private: typedef void (*FUN)(void*); FUN f_, g_; void* x_; }; void test() { try { Tst_2 t2; Interface i(&t2); i.f(); i.g(); Tst_1 t1; i = &t1; i.f(); i.g(); } catch (FUN f) { std::cout << "exception: trying to access fun " << f << std::endl; } } } #endif