0Pricing
C++ Academy · Lesson

Mixins with CRTP

Compose behavior at compile time.

Mixins with CRTP is a free C++ Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C++ Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

What Is a Mixin?

A mixin is a small reusable unit of behavior you compose into a class. With CRTP, mixins add functionality at compile time while still calling into the host class.

A Simple Mixin

This mixin adds a print_twice method that relies on the host providing value().

#include <iostream>

template <typename T>
struct PrintTwice {
    void print_twice() const {
        auto v = static_cast<const T*>(this)->value();
        std::cout << v << " " << v << "\n";
    }
};

struct Box : PrintTwice<Box> {
    int value() const { return 7; }
};

int main() {
    Box{}.print_twice();
    return 0;
}

Composing Multiple Mixins

You can inherit from several CRTP mixins at once, stacking independent behaviors onto one class.

#include <iostream>

template <typename T>
struct Loggable {
    void log() const { std::cout << "log: " << static_cast<const T*>(this)->id() << "\n"; }
};

template <typename T>
struct Resettable {
    void reset() { static_cast<T*>(this)->set(0); }
};

struct Device : Loggable<Device>, Resettable<Device> {
    int v = 5;
    int id() const { return v; }
    void set(int x) { v = x; }
};

int main() {
    Device d;
    d.log();
    d.reset();
    d.log();
    return 0;
}

Mixins Add State Too

A mixin can carry its own data members, which become part of the composed object layout.

#include <iostream>

template <typename T>
struct Tagged {
    int tag = 0;
    void set_tag(int t) { tag = t; }
    int get_tag() const { return tag; }
};

struct Item : Tagged<Item> {
    const char* name = "item";
};

int main() {
    Item it;
    it.set_tag(42);
    std::cout << it.name << " " << it.get_tag() << "\n";
    return 0;
}

Mixin vs Plain Inheritance

A CRTP mixin differs from ordinary inheritance because the base can call down into the derived class. Ordinary base classes cannot call methods that only exist on the derived type without virtuals.

Policy-Based Design

Mixins enable policy-based design: behaviors are selected at compile time by choosing which mixins to inherit, similar to how std::vector takes an allocator policy.

Ordering and Layout

When stacking mixins, the order of bases affects construction order and object layout. Keep mixins independent so order does not matter for correctness.

  • Construct in declaration order of bases
  • Avoid mixins that depend on each other

Adding an Equality Mixin

Here a mixin synthesizes operator!= from the host equality.

#include <iostream>

template <typename T>
struct EqualityMixin {
    friend bool operator!=(const T& a, const T& b) { return !(a == b); }
};

struct P : EqualityMixin<P> {
    int x;
    P(int v) : x(v) {}
    friend bool operator==(const P& a, const P& b) { return a.x == b.x; }
};

int main() {
    std::cout << (P(1) != P(2)) << "\n";
    return 0;
}

Conditional Mixins

You can include a mixin only when a condition holds by combining inheritance with std::conditional, choosing between a real mixin and an empty one.

Empty Base Optimization

Mixins that hold no data members benefit from the Empty Base Optimization: the compiler allocates zero extra bytes for them, so stacking many stateless mixins is free in terms of size.

#include <iostream>

template <typename T>
struct A {};
template <typename T>
struct B {};

struct C : A<C>, B<C> {
    int x;
};

int main() {
    std::cout << (sizeof(C) == sizeof(int)) << "\n";
    return 0;
}

When to Reach for Mixins

Mixins shine when many classes need the same orthogonal behaviors (logging, counting, comparison). They keep each behavior in one place and compose without runtime cost.

Quick Check

Test your grasp of CRTP mixins.

Recap

You learned to build mixins with CRTP.

  • Mixins compose orthogonal behavior at compile time
  • They can call down into the host and carry state
  • Stateless mixins are free thanks to Empty Base Optimization
  • Great for logging, comparison, counting policies

Frequently asked questions

Is the “Mixins with CRTP” lesson free?

Yes — the full text of “Mixins with CRTP” is free to read here on the web, and the C++ Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C++ Academy course, upgrade to CoddyKit PRO.

What will I learn in “Mixins with CRTP”?

Compose behavior at compile time. You practise C++ Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C++ Academy?

No prior experience is required. C++ Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Mixins with CRTP” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C++ Academy lesson?

Yes. Every C++ Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. The CRTP Idiom
  2. Static Polymorphism
  3. Mixins with CRTP
  4. When to Use CRTP
← Back to C++ Academy