Swiftorial Logo
Home
Swift Lessons
Tutorials
Learn More
Career
Resources

CRTP (Curiously Recurring Template Pattern) Tutorial

Introduction

The Curiously Recurring Template Pattern (CRTP) is a C++ idiom where a class template is derived from itself. This pattern is used to achieve static polymorphism, which allows the compiler to resolve function calls at compile-time, providing performance benefits and potentially better optimization opportunities.

Basic Concept

In CRTP, a class Derived inherits from a template class Base, where Base is parameterized by Derived itself. This creates a recursive inheritance relationship.

Example:

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

class Derived : public Base<Derived> {
public:
    void implementation() {
        // Derived-specific implementation
    }
};
                

Benefits of CRTP

CRTP provides several benefits:

  • Static Polymorphism: The function calls are resolved at compile-time, which avoids the overhead of virtual function calls.
  • Code Reusability: Common functionality can be implemented in the base class and reused in derived classes.
  • Compile-time Checking: Errors can be caught at compile-time rather than runtime.

Example: Static Polymorphism

Let's consider a scenario where we want different derived classes to implement a common interface. CRTP allows us to achieve this without virtual functions:

Example:

#include <iostream>

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

class Derived1 : public Base<Derived1> {
public:
    void implementation() {
        std::cout << "Derived1 implementation" << std::endl;
    }
};

class Derived2 : public Base<Derived2> {
public:
    void implementation() {
        std::cout << "Derived2 implementation" << std::endl;
    }
};

int main() {
    Derived1 d1;
    Derived2 d2;
    d1.interface();
    d2.interface();
    return 0;
}
                
Output:
Derived1 implementation
Derived2 implementation
                

Advanced Usage: Mixins

CRTP can be extended to create mixin classes, allowing multiple inheritance of behavior. This can be particularly useful for composing different functionalities.

Example:

#include <iostream>

template <typename T>
class Mixin1 {
public:
    void feature1() {
        static_cast<T*>(this)->feature1_impl();
    }
};

template <typename T>
class Mixin2 {
public:
    void feature2() {
        static_cast<T*>(this)->feature2_impl();
    }
};

class Combined : public Mixin1<Combined>, public Mixin2<Combined> {
public:
    void feature1_impl() {
        std::cout << "Feature 1 implementation" << std::endl;
    }
    
    void feature2_impl() {
        std::cout << "Feature 2 implementation" << std::endl;
    }
};

int main() {
    Combined c;
    c.feature1();
    c.feature2();
    return 0;
}
                
Output:
Feature 1 implementation
Feature 2 implementation
                

Conclusion

The Curiously Recurring Template Pattern (CRTP) is a powerful technique in C++ for achieving static polymorphism and code reuse. It leverages template inheritance to allow derived classes to implement specific behavior while avoiding the overhead of virtual function calls. By understanding and applying CRTP, developers can write more efficient and maintainable C++ code.