What is type erasure in C++?

Here’s a very simple example of type erasure in action:

// Type erasure side of things

class TypeErasedHolder
{
  struct TypeKeeperBase
  {
    virtual ~TypeKeeperBase() {}
  };

  template <class ErasedType>
  struct TypeKeeper : TypeKeeperBase
  {
    ErasedType storedObject;

    TypeKeeper(ErasedType&& object) : storedObject(std::move(object)) {}
  };

  std::unique_ptr<TypeKeeperBase> held;

public:
  template <class ErasedType>
  TypeErasedHolder(ErasedType objectToStore) : held(new TypeKeeper<ErasedType>(std::move(objectToStore)))
  {}
};

// Client code side of things

struct A
{
  ~A() { std::cout << "Destroyed an A\n"; }
};

struct B
{
  ~B() { std::cout << "Destroyed a B\n"; }
};

int main()
{
  TypeErasedHolder holders[] = { A(), A(), B(), A() };
}

[Live example]

As you can see, TypeErasedHolder can store objects of an arbitrary type, and destruct them correctly. The important point is that it does not impose any restrictions on the types supported(1): they don’t have to derive from a common base, for example.


(1) Except for being movable, of course.

Leave a Comment