Type Erasure

Learn the type erasure pattern to utilize common functionalities from unrelated types.

The term type erasure describes a pattern in which type information is removed, allowing types that are not necessarily related to be treated in a generic way. This isn’t something specific to the C++ language. This concept exists in other languages with better support than in C++ (such as Python and Java). There are different forms of type erasure, such as polymorphism and using void pointers (a legacy of the C language, which is to be avoided), but true type erasure is achieved with templates. Before we discuss this, let’s briefly look at the others.

Press + to interact

The most rudimentary form of type erasure is the use of void pointers. This is typical of C, and although possible in C++, it’s in no way recommended. It isn’t type-safe and, therefore, is error prone. However, for the sake of the discussion, let’s have a look at such an approach.

C-like type erasure

Let’s say we again have knight and mage types and they both have an attack function (a behavior), and we want to treat them in a common way to exhibit this behavior. Let’s see the classes first:

struct knight
{
void attack() { std::cout << "draw sword\n"; }
};
struct mage {
void attack() { std::cout << "spell magic curse\n"; }
};
The knight and the mage classes with the member function attack

In a C-like implementation, we could have a function for each of these types, taking a void* to an object of the type, casting it to the expected type of pointer, and then invoking the attack member function:

void fight_knight(void* k)
{
reinterpret_cast<knight*>(k)->attack();
}
void fight_mage(void* m)
{
reinterpret_cast<mage*>(m)->attack();
}
Defining functions to receive the void pointer references

These have a similar signature; the only thing that differs is the name. So, we can define a function ...