Listing 1
// a baz "interface" class baz { public: // forward declarations template <class T> struct functions; // interface calls template <class T> baz(T& x) : _m_a(&x), _m_t(&functions<T>::table) {} int foo(int x) { return _m_t->foo(const_cast<void*>(_m_a), x); } int bar(char const* x) { return _m_t->bar(const_cast<void*>(_m_a), x); } // Function table type for the baz interface struct table { int (*foo)(void*, int x); int (*bar)(void*, char const*); }; // For a given referenced type T, generates functions for the // function table and a static instance of the table. template <class T> struct functions { static baz::table const table; static int foo(void* p, int x) { return static_cast<T*>(p)->foo(x); } static int bar(void* p, char const* x) { return static_cast<T*>(p)->bar(x); } }; private: void const* _m_a; table const* _m_t; }; template <class T> baz::table const baz::functions<T>::table = { &baz::functions<T>::foo , &baz::functions<T>::bar }; #include <cstring> #include <cstdio> struct some_baz { int foo(int x) { return x + 1; } int bar(char const* s) { return std::strlen(s); } }; struct another_baz { int foo(int x) { return x - 1; } int bar(char const* s) { return -std::strlen(s); } }; int main() { some_baz f; another_baz f2; baz p = f; std::printf("p.foo(3) = %d\n", p.foo(3)); std::printf("p.bar(\"hi\") = %d\n", p.bar("hi")); p = f2; std::printf("p.foo(3) = %d\n", p.foo(3)); std::printf("p.bar(\"hi\") = %d\n", p.bar("hi")); }