Curiously Recurring Template Pattern (CRTP)

The Curiously Recurring Template Pattern (CRTP) is a C++ idiom where a base class takes a derived class as a template parameter. This allows the base class to call methods from the derived class without virtual functions, leading to better performance and compile-time polymorphism.

🔹 Basic Structure of CRTP

template <typename Derived>
class Base {
public:
    void interface() {
        static_cast<Derived*>(this)->implementation();
    }
};

class Derived : public Base<Derived> {
public:
    void implementation() {
        std::cout << "Derived class implementation\n";
    }
};

int main() {
    Derived d;
    d.interface(); // Calls Derived::implementation() via Base
}

No virtual functions → Faster execution
Compile-time polymorphism → No runtime overhead


🔹 Why Use CRTP?

CRTP is useful for:
Static Polymorphism – Avoids virtual function overhead.
Mixin Classes – Adding behavior without multiple inheritance complexity.
Method Overriding – Derived class methods can be called from the base class.
Compile-time Interface Checking – Ensures certain methods exist in the derived class.


🔹 CRTP Use Cases in C++

1️⃣ Compile-Time Polymorphism

Instead of using virtual functions, CRTP allows method overriding at compile-time.

#include <iostream>

template <typename Derived>
class Base {
public:
    void greet() {
        static_cast<Derived*>(this)->greetImpl();
    }
};

class English : public Base<English> {
public:
    void greetImpl() {
        std::cout << "Hello!\n";
    }
};

class Spanish : public Base<Spanish> {
public:
    void greetImpl() {
        std::cout << "¡Hola!\n";
    }
};

int main() {
    English e;
    Spanish s;
    e.greet(); // Hello!
    s.greet(); // ¡Hola!
}

Compile-time dispatch instead of runtime polymorphism
✅ No need for virtual functions, making the code more efficient


2️⃣ Mixin Pattern (Adding Functionality)

CRTP allows adding behavior without multiple inheritance issues.

template <typename Derived>
class Logger {
public:
    void log(const std::string& message) {
        std::cout << "[LOG] " << message << "\n";
    }
};

class Application : public Logger<Application> {
public:
    void run() {
        log("Application started!");
    }
};

int main() {
    Application app;
    app.run(); // Output: [LOG] Application started!
}

Lightweight mixins
No virtual table (vtable) overhead


3️⃣ Method Enforcement in Derived Classes

CRTP can enforce that a derived class implements a required method.

template <typename Derived>
class Base {
public:
    void execute() {
        static_cast<Derived*>(this)->process();
    }
};

class ValidDerived : public Base<ValidDerived> {
public:
    void process() {
        std::cout << "Processing...\n";
    }
};

// class InvalidDerived : public Base<InvalidDerived> {}; // ERROR! Missing process()

int main() {
    ValidDerived v;
    v.execute(); // Output: Processing...
}

Compile-time method enforcement
✅ No need for abstract base classes


4️⃣ Counting Objects (Static Data in CRTP)

CRTP allows each derived class to have its own static members.

template <typename Derived>
class Counter {
public:
    static int count;
    
    Counter() { ++count; }
    ~Counter() { --count; }
    
    static int getCount() { return count; }
};

template <typename Derived>
int Counter<Derived>::count = 0;

class A : public Counter<A> {};
class B : public Counter<B> {};

int main() {
    A a1, a2;
    B b1;
    
    std::cout << "A count: " << A::getCount() << "\n"; // Output: A count: 2
    std::cout << "B count: " << B::getCount() << "\n"; // Output: B count: 1
}

✅ Each derived class gets its own static count
✅ No global static variables


🔹 CRTP vs Virtual Functions

FeatureCRTPVirtual Functions
Polymorphism TypeCompile-timeRuntime
PerformanceFaster (no vtable)Slower (due to vtable lookup)
FlexibilityLess flexibleMore flexible (supports dynamic dispatch)
Memory OverheadNonevtable adds memory overhead
Use CaseKnown types at compile-timeNeed runtime polymorphism

📌 Use CRTP when performance matters and you don’t need runtime polymorphism.
📌 Use virtual functions when you need dynamic behavior.


🔹 Summary

✅ CRTP is a powerful design pattern for compile-time polymorphism.
✅ It removes the need for virtual functions, making the code faster.
✅ It’s useful for mixins, method enforcement, and static polymorphism.
✅ Each derived class can have independent static members.