All type erasure techniques in C++ are done with function pointers (for behaviour) and void*
(for data). The “different” methods simply differ in the way they add semantic sugar. Virtual functions, e.g., are just semantic sugar for
struct Class {
struct vtable {
void (*dtor)(Class*);
void (*func)(Class*,double);
} * vtbl
};
iow: function pointers.
That said, there’s one technique I particularly like, though: It’s shared_ptr<void>
, simply because it blows the minds off of people who don’t know you can do this: You can store any data in a shared_ptr<void>
, and still have the correct destructor called at the end, because the shared_ptr
constructor is a function template, and will use the type of the actual object passed for creating the deleter by default:
{
const shared_ptr<void> sp( new A );
} // calls A::~A() here
Of course, this is just the usual void*
/function-pointer type erasure, but very conveniently packaged.