♻️Go deeper — read the bookCRTP: Curiously Recurring Template Pattern— runnable code & full walkthrough →

cpp core · advanced

CRTP: Static vs Dynamic Polymorphism

The base takes the derived as a template arg, so calls bind at compile time - zero-overhead static polymorphism vs runtime virtual dispatch.

🔑 Key line

CRTP = static polymorphism: Base<Derived> resolves calls at compile time (no vptr, inlinable); virtual resolves at runtime.

The code

template <class Derived>
struct Shape {
void draw() { // non-virtual!
static_cast<Derived*>(this)->draw_impl();
}
};
struct Circle : Shape<Circle> { // passes ITSELF as the arg
void draw_impl() { /* draw a circle */ }
};
Shape<Circle> c;
c.draw(); // -> Circle::draw_impl(), inlined

What this lesson walks through

  1. 01The CRTP pattern
  2. 02Base calls down via static_cast
  3. 03Resolved at COMPILE time -> inlinable
  4. 04Contrast: virtual binds at RUNTIME
  5. 05The cost difference
  6. 06The trade-off

In the Curiously Recurring Template Pattern, a class derives from a base templated on itself: struct Circle : Shape<Circle>. The base now knows its derived type as a template parameter.

See it animated — step by step, at your own pace

Unlock the full interactive walkthrough of CRTP: Static vs Dynamic Polymorphism and 100+ animated C++ interview lessons.

← Previous
Rule of 5 — Writing a String Class
Next →
Type Erasure & std::function