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"));
}