CRTP: A Curious Polymorphism Idiom
Polymorphism in C++
- Definition: the use of a single symbol to represent multiple different types
- Compile-time (static) polymorphism
- Function overloading: implemented by name mangling, not available in C
- Operator overloading: similar as function overloading
- Templates
- CRTP <- today we focus on
- Runtime (dynamic) polymorphism
- Function overriding (virtual) -> also can be inferred early at compile time / constexpr virtual (C++20)
- std::optional (C++17)
- std::variant (C++17)
- ...
- A takeaway here: look into if variables can be inferred during compile time
- We prefer compile-time polymorphism in common, but still need to be aware of the overhead
- Binary size
- Codebase complexity
A Curious Idiom: CRTP
- CRTP stands for Curiously Recurring Template Pattern
- a class X derives from a class template instantiation using X itself as a template argument
template <class T>
class X { … };
class A : public X<A> {...};
- Used for enhancement or semantic extension
- No virtual (virtual is not bad fairly speaking)
Why can CRTP compile
When to use CRTP
- Mixin, when you feel like
- it’s more like an enhancement to existing classes
- it can be "included" rather than "inherited"
- you don’t need type erasure
- Demos
- In practices
Miscellaneous
- Pitfalls
- Type erasure
- virtual comes with type erasure, but CRTP not
- without using a general base class like AbstractShape from the above example, derived classes cannot be stored homogeneously
- std::vector<Shape*> doesn’t work
- solution: inherit from a shared base class with a virtual destructor (like AbstractShape, but back to virtual again…)
- Best Practices
- use “friend trick” to avoid potential mistakes
- CRTP in C++23
- Benchmarks
All rights reserved
Except where otherwise noted, content on this page is copyrighted.