CRTP — using derived class as template parameter for base class.
1// Base class takes Derived as template parameter2template<typename Derived>3class Base {4public:5 void interface() {6 // Cast to derived and call implementation7 static_cast<Derived*>(this)->implementation();8 }9};1011// Derived passes itself as template argument12class Derived : public Base<Derived> {13public:14 void implementation() {15 std::cout << "Derived implementation\n";16 }17};1819int main() {20 Derived d;21 d.interface(); // Calls Derived::implementation22}
Use cases:
1. Static polymorphism (no vtable):
1template<typename Derived>2class Shape {3public:4 void draw() const {5 static_cast<const Derived*>(this)->draw_impl();6 }7};89class Circle : public Shape<Circle> {10public:11 void draw_impl() const {12 std::cout << "Drawing circle\n";13 }14};
2. Mixins:
1template<typename Derived>2class Singleton {3public:4 static Derived& getInstance() {5 static Derived instance;6 return instance;7 }8};910class Logger : public Singleton<Logger> {11 // ...12};
Advantages: