A step-by-step derivation of how std::any's type erasure works internally, starting from familiar interface-based polymorphism using virtual functions, then showing the limitations of template-based polymorphism, and finally combining wrappers and templates to build a minimal, working type-erased 'Any' class from scratch using C++ shape examples.

7m read timeFrom david.alvarezrosa.com
Post cover image
Table of contents
Polymorphism with interfaces §Polymorphism with templates §Deriving std::any §Generic std::any §

Questions this post answers

What is type erasure in C++ and how does std::any implement it internally?

Type erasure is a technique that hides concrete types behind a uniform interface using a combination of virtual functions and templates. An inner abstract 'Concept' class defines the interface, and a templated 'Model' class inherits from Concept, wraps a concrete object, and forwards calls to it. The outer class holds a unique_ptr to Concept, letting callers store any type without knowing it, which is exactly how std::any and std::function work under the hood. Developers untangling std::any internals can dig deeper into type erasure patterns on daily.dev.

What are the downsides of using templates instead of virtual functions for polymorphism in C++?

Template-based polymorphism has two main drawbacks: each instantiation produces a distinct type, so there's no common base type to store mixed types in one container like a vector, and every caller of a templated function must either specify the concrete type explicitly or become a template itself to forward the type, which spreads templates across a codebase and increases compile times and binary size. Weighing templates against virtual interfaces for a C++ design is easier with resources like this on daily.dev.

1.2K Impressions