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.
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"; }};
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();}
These have a similar signature; the only thing that differs is the name. So, we can define a function ...