Skip to content

Comment on Type Erasure in C++ Explained

Comments

But the result is beautiful.

Ugly as hell, ouch! Really?

GNU C++ had something called signatures years ago, which was removed. It was far more elegant.

You could declare a signature which was a class-like thing: function declarations in curly braces.

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).

Found a nice document on it:

https://csc.lsu.edu/~gb/Signatures/index.html

So, here is how the code would look:

  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);
  }
When foo is called with bar, a Do & signature reference is taken to bar. This is allowed because the type Bar has all the functions declared in the signature type Do, making it compatible.

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.

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.

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.

If that can be set up at compile time, then maybe the Do &doer argument just has to be some sort of fat reference consisting of the pointer to bar, and to the __Do_Bar_table which translates the Do calls into Bar calls.

It seems cheaper than the convolution presented in this article.

Signatures didn't make it into ISO C++, but since that time, a lot of cruft has which is worse.

Looks like this 1999 commit may be what removed signatures:

https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=6eabb2412f6c4c...

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:

https://gcc.gnu.org/pipermail/gcc/1999-August/035433.html

"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."

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.

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.

They removed a good thing on a whim.

In C++20, this is called a "concept"

It's more closely related to the `concept` from the Indiana proposal from C++0x (which is structural) rather than the one in C++20, which is most like the expression syntax. (That syntax was lifted nearly unscathed from Spad.)

They're both missing the Indiana `concept_map` which were runtime-free functors -- like -- proper functors.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.