Type Erasure is useful in an extraordinary amount of situations, to the point where it may actually be thought of as a fundamentally missing language feature that bridges generic and object oriented programming styles.
When we define a class in C++, what we are really defining is both a very specific type
and a very specific interface
, and that these two things do not necessarily need to be related. A type
deals with the data, where as the interface
deals with transformations on that data. Generic code, such as in the STL, doesn't care about type
, it cares about interface
: you can sort anything container or container-like sequence using std::sort
, as long as it provides comparison and iterator interface
.
Unfortunately, generic code in C++ requires compile time polymorphism: templates
. This doesn't help with things which cannot be known until runtime, or things which require a uniform interface.
A simple example is this: how do you store a number of different types in a single container? The simplest mechanism would be to store all of the types in a void*, perhaps with some type information to distinguish them. Another way is to recognize all of these types
have the same interface
: retrieval. If we could make a single interface for retrieval
, then specialize it for each type, then it would be as if part of the type
had been erased.
any_iterator
is another very useful reason to do this: if you need to iterate over a number of different containers with the same interface, you will need to erase the type
of the container out of the type
of the iterator. boost::any_range is a subtle enhancement of this, extending it from iterators to ranges, but the basic idea is the same.
In short, any time you need to go from multiple types
with a similar interface
to a single type
with a single interface
, you will need some form of type erasure. It is the runtime technique that equates compile time templates.