> <i>But the result is beautiful.</i><p>Ugly as hell, ouch! Really?<p>GNU C++ had something called signatures years ago, which was removed. It was far more elegant.<p>You could declare a <i>signature</i> which was a class-like thing: function declarations in curly braces.<p>Having that signature declared, you could lift a pointer of that type to any object which had those functions (without any relationship to the signature having to be declared by that object).<p>Found a nice document on it:<p><a href="https://csc.lsu.edu/~gb/Signatures/index.html" rel="nofollow">https://csc.lsu.edu/~gb/Signatures/index.html</a><p>So, here is how the code would look:<p><pre><code> class Bar { // nothing to inherit here
public:
void doSomething() { }
};
signature Do {
void doSomething();
};
void foo(Do &doer)
{
doer.doSomething();
}
int main()
{
Bar bar;
foo(bar);
}
</code></pre>
When <i>foo</i> is called with <i>bar</i>, a <i>Do &</i> signature reference is taken to <i>bar</i>. This is allowed because the type Bar has all the functions declared in the signature type Do, making it compatible.<p>Sure, the implementation has to bend over backwards. But signatures are more declarative, so the implementation has a clearer idea of your intent. It can do whatever magic is required.<p>It seems clear to me that there is a static way to bind the Do signature reference to the Bar type. You probably have to construct some vtable like object which does the right sort of indirection.<p>The translation unit could emit some hidden __Do__Bar_table item which does exactly that: it's a vtable-like table made in the shape of Do, which is filled with pointers (perhaps fat pointers with offsets and whatever is necessary) to the matching functions in Bar.<p>If that can be set up at compile time, then maybe the <i>Do &doer</i> argument just has to be some sort of fat reference consisting of the pointer to <i>bar</i>, and to the __Do_Bar_table which translates the Do calls into Bar calls.<p>It seems cheaper than the convolution presented in this article.<p>Signatures didn't make it into ISO C++, but since that time, a lot of cruft has which is worse.<p>Looks like this 1999 commit may be what removed signatures:<p><a href="https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=6eabb2412f6c4c8306fb2f8fd05abf608e29caa9" rel="nofollow">https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=6eabb2412f6c4c...</a><p>It doesn't point to any information about the removal. We probably have to dig into mailing lists. At least it gives a date, thanks to which we can find this posting. Unfortunately, the one from which it quotes is missing for some reason:<p><a href="https://gcc.gnu.org/pipermail/gcc/1999-August/035433.html" rel="nofollow">https://gcc.gnu.org/pipermail/gcc/1999-August/035433.html</a><p>"This patch removes support for `signature', a g++ extension that is little-used and which Jason and I agreed should go. The reduction in complexity elsewhere in the front-end will be a big win."<p>OMG, you would absolutely not see this today in C++ development. "Jason and I" decided that some C++ gadget is too little used and we will remove it.<p>How naive that seems; these people had no idea about the deluge of garbage that was coming down the pipe into standard C++ over the following two decades, that they would have to implement.<p>They removed a good thing on a whim.