CRTP is a C++ idiom where a class Derived inherits from a template base class that is instantiated with Derived itself.
class Derived : public Base<Derived> {
// ...
};
๐ Intuition:
class Base {
// typical base class
};
// CRTP base
template<typename Derived>
class Base {
void interface() {
static_cast<Derived*>(this)->implementation();
}
};
class Derived : public Base<Derived> {
public:
void implementation() {
std::cout << "Derived implementation\\\\n";
}
};
static_cast<Derived*>(this): Tells compiler to treat this pointer of Base as pointer to Derived.| Feature | CRTP (Compile-time) | Virtual (Runtime) |
|---|---|---|
| Dispatch | Static | Dynamic |
| Overhead | Zero (inlined) | Virtual table lookup |
| Use | Performance-critical code | Polymorphism with runtime flexibility |
// Virtual Example
class Animal {
public:
virtual void speak() { std::cout << "Animal sound\\\\n"; }
};
class Dog : public Animal {
public:
void speak() override { std::cout << "Bark!\\\\n"; }
};
void make_sound(Animal* a) {
a->speak(); // Runtime dispatch
}
// CRTP Example
template<typename Derived>
class AnimalBase {
public:
void speak() {
static_cast<Derived*>(this)->speak();
}
};
class Dog : public AnimalBase<Dog> {
public:
void speak() { std::cout << "Bark!\\\\n"; }
};
void make_sound(Dog* d) {
d->speak(); // Compile-time dispatch
}