Skip to content

Instantly share code, notes, and snippets.

@quietfanatic
Created June 14, 2012 13:10
Show Gist options
  • Save quietfanatic/2930211 to your computer and use it in GitHub Desktop.
Save quietfanatic/2930211 to your computer and use it in GitHub Desktop.
Go-style interfaces in C++
#include <stdio.h>
class Talking {
// Vtable
template <class T>
struct implemented_by {
void (T::* talk ) ();
void (T::* talk__int ) (int);
static const implemented_by vtable;
};
// Interface struct is two pointers long
const implemented_by<Talking>*const vt;
Talking*const p;
public:
// Methods
inline void talk () { return (p->*(vt->talk))(); }
inline void talk (int x) { return (p->*(vt->talk__int))(x); }
// Conversion
template <class T>
Talking (T* x)
:vt(reinterpret_cast<const implemented_by<Talking>*>(&implemented_by<T>::vtable)),
p(reinterpret_cast<Talking*>(x))
{ }
};
// Define vtables for all compatible types
template <class T>
const Talking::implemented_by<T> Talking::implemented_by<T>::vtable = {
&(T::talk),
&(T::talk)
};
/*
INTERFACE( Talking,
ITFcaptures(
ITFcapture(talk)
ITFcapture(talk)
)
ITFvtable(
ITFvfunc(void, talk, ())
ITFvfunc(void, talk__int, (int))
),
ITFmapping(
ITFmap(void talk (), talk, ())
ITFmap(void talk (int x), talk__int, (x))
),
)
*/
// No "implements" declaration, no virtual methods
struct Foo {
int x;
void talk () {
printf("I'm a Foo with a %d!\n", x);
}
void talk (int num) {
printf("That's a mighty fine %d there.\n", num);
}
};
struct Bar {
void talk () {
printf("I can only say one thing.\n");
}
};
void talkabout (Talking t) {
t.talk();
t.talk(4);
}
int main () {
// Watch the magic.
Foo foo = {24};
talkabout(&foo);
// Bar bar;
// talkabout(&bar); // Not too bad of an error message
printf("%d\n", sizeof(Talking));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment