I would also consider (similar to void ) the use of "raw storage": char bufferN.
I would also consider (similar to void*) the use of "raw storage": char bufferN. In C++0x you have std::aligned_storage for this. You can store anything you want in there, as long as it's small enough and you deal with the alignment properly.
1 Well yeah, Boost. Function actually uses a combination of this and the second example I gave. If the functor is small enough, it stores it internally inside the functor_buffer.
Good to know about std::aligned_storage though, thanks! :) – Xeo Mar 27 at 16:21.
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, 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, 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 sp( new A ); } // calls A::~A() here Of course, this is just the usual void*/function-pointer type erasure, but very conveniently packaged.
1 Coincidentally, I had to explain the behaviour of shared_ptr to a friend of mine with an example implementation just some days ago. :) It really is cool. – Xeo May 18 at 12:36.
Fundamentally, those are your options: virtual functions or function pointers. How you store the data and associate it with the functions can vary. For example, you could store a pointer-to-base, and have the derived class contain the data and the virtual function implementations, or you could store the data elsewhere (e.g.In a separately allocated buffer), and just have the derived class provide the virtual function implementations, which take a void* that points to the data.
If you store the data in a separate buffer, then you could use function pointers rather than virtual functions. Storing a pointer-to-base works well in this context, even if the data is stored separately, if there are multiple operations that you wish to apply to your type-erased data. Otherwise you end up with multiple function pointers (one for each of the type-erased functions), or functions with a parameter that specifies the operation to perform.
Though, thanks for writing it up like this, especially w.r.t. To the virtual functions and multiple operations on the type-erased data. – Xeo May 17 at 17:28 There are at least 2 other options.
I am composing an answer. – John Dibling May 17 at 18:57.
In C++ you shouldn't really do type erasure. C++ does everything like this automatically. For example, const works like that in C++.
Const has no effect on the generated code and thus was erased from the compiled program. Instead of type erasure, a common pattern is to move the type to runtime via void* and typeid(T).
1 I think you don't understand the meaning of type erasue. :| Look at the two example codes provided by the Ideone link in my question and at my discussion with Oli in the comments. Also, void* is a type erasure technique, again, see my example codes.
– Xeo May 15 at 18:08 no, the reason for type erasure is that the types and type checking does make some dynamic behaviour in the program impossible. But the real problem is that types are only in compile-time, and you don't need to go that far as doing complete type erasure, instead, you can just move the types to runtime. – tp1 May 15 at 19:15 @xeo that's what happens when you use a term like type erasure, which has a specific meaning, as if it meant something else.
Boost::any doesn't do compile-time type erasure, it just throws away some information at runtime. – amalloy May 16 at 5:17 4 @amalloy I'm with Xeo on that one; if you google "c++ type erasure" you can see the term is well understood in the C++ community. It's unfortunate that it's shared with other usages.(Probably to blame to a lack of imagination).
– Luc Danton May 16 at 17:28 1 @amalloy: That's not Xeo's fault. The term is in general usage for this technique. – sbi May 17 at 17:08.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.