Skip to content

Last updated:2026-10-12

C++ Mixin Idiom

Hello everyone, I am 光城. Today I am sharing one of the idioms from C++那些事: mixin

Mixins are a concept from Lisp. A mixin is a piece of a class, meaning it is intended to be combined with other classes or mixins. The difference between a regular standalone class (such as Person) and a mixin is that a mixin models some small piece of functionality (such as printing or displaying) and is not meant to be used standalone. Instead, it is meant to be combined with other classes that need that functionality (such as Person).

Therefore, the purpose of mixins is to allow something similar to multiple inheritance.

The basic form of a mixin in C++ is as follows:

template <class Super>
class Mixin : public Super {
. /* mixin body */
};

or

template<typename... Super>
class Mixin : public Super... {
  public:
    Mixin() :  Super...() {}
  // ...
};

Note: all the sample code in this section is available from the Knowledge Planet.

Example 1: Scaling and Rotation

Suppose we want to scale, rotate, and add a border to a rectangle/square — all operations that affect its width and height; we can implement this with mixins.

First, we can define the square and the rectangle as the base classes of the mixin.

// 正方形类
class Square : public Shape {
public:
    Square(int sideLength) : sideLength(sideLength) {}
    int GetWidth() const override { return sideLength; }
    int GetHeight() const override { return sideLength; }
private:
    int sideLength;
};

// 长方形类
class Rectangle : public Shape {
public:
    Rectangle(int width, int height) : width(width), height(height) {}
    int GetWidth() const override { return width; }
    int GetHeight() const override { return height; }
private:
    int width;
    int height;
};

Then use mixin subclasses to extend the functionality. For example: for a scaling mixin we can write a custom class whose width and height equal scale multiplied by the corresponding width and height.

// 缩放的Mixin
template <class Base, int ScaleX, int ScaleY>
class Scale : public Base {
 public:
  int GetScaledWidth() const { return Base::GetWidth() * ScaleX; }
  int GetScaledHeight() const { return Base::GetHeight() * ScaleY; }
};

Scenarios like this are a perfect fit for mixins.

Usage:

using ModifiedShape = Border<RotateBy90<Scale<Square, 2, 1>>, 10>;

Example 2: redo and undo

The complete example simulates redo and undo operations, so that we can switch back and forth between data. With Redoable<Undoable<Number>>, we can mix these classes together and use them.

#include <iostream>

using namespace std;

struct Number {
    typedef int value_type;
    int n;
    void set(int v) {
        n = v;
    }
    int get() const {
        return n;
    }
};

template <typename BASE, typename T = typename BASE::value_type>
struct Undoable : public BASE {
    typedef T value_type;
    T before;
    void set(T v) {
        before = BASE::get();
        BASE::set(v);
    }
    void undo() {
        BASE::set(before);
    }
};

template <typename BASE, typename T = typename BASE::value_type>
struct Redoable : public BASE {
    typedef T value_type;
    T after;
    void set(T v) {
        after = v;
        BASE::set(v);
    }
    void redo() {
        BASE::set(after);
    }
};

typedef Redoable<Undoable<Number>> ReUndoableNumber;

int main() {
    ReUndoableNumber mynum;
    mynum.set(42);
    mynum.set(84);
    cout << mynum.get() << '\n';  // Output: 84
    mynum.undo();
    cout << mynum.get() << '\n';  // Output: 42
    mynum.redo();
    cout << mynum.get() << '\n';  // Output: back to 84
}

Example 3: Repeated Printing

Here is another building-block example: repeated printing.

First, there is a class with which we can print a person's name.

class Name
{
public:
    Name(std::string firstName, std::string lastName)
      : firstName_(std::move(firstName))
      , lastName_(std::move(lastName)) {}

    void print() const
    {
        std::cout << lastName_ << ", " << firstName_ << '\n';
    }

private:
    std::string firstName_;
    std::string lastName_;
};

But what if I want to print it repeatedly?

We can play it like this: use a mixin and pass the Name class in.

template<typename Printable>
struct RepeatPrint : Printable
{
    explicit RepeatPrint(Printable const& printable) : Printable(printable) {}
    void repeat(unsigned int n) const
    {
        while (n-- > 0)
        {
            this->print();
        }
    }
};

template<typename Printable>
RepeatPrint<Printable> repeatPrint(Printable const& printable)
{
    return RepeatPrint<Printable>(printable);
}

Usage:

Name ned("Eddard", "Stark");    
repeatPrint(ned).repeat(10);

Now we get the printout repeated n times.

So which scenarios suit mixins best?

  • Keeping the original class unchanged,
  • Client code does not use the raw class directly; it has to wrap it in a mixin to gain the enhanced functionality,

Standard Library

There is a use of the mixin technique in the standard library: std::nested_exception.

std::nested_exception is a polymorphic mixin class that can capture and store the currently handled exception, allowing exceptions of arbitrary types to be nested within one another.

template <typename _Except>
struct _Nested_exception : public _Except, public nested_exception
{}

In the source we can see nested_exception used as the mixin base class.

References

https://cedanet.com.au/ceda/Xc++/$mixin/mixins-in-straight-c++.php

https://www.fluentcpp.com/2017/12/12/mixin-classes-yang-crtp/

https://stackoverflow.com/questions/18773367/what-are-mixins-as-a-concept

Comments