Created
June 14, 2012 13:10
-
-
Save quietfanatic/2930211 to your computer and use it in GitHub Desktop.
Go-style interfaces in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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