In my previous post “More about Dynamic and Static Polymorphism”, I used the Curiously Recurring Template Pattern (CRTP) to implement static polymorphism. Another typical use case for CRTP is mixins.
Mixins are a popular idea in the design of classes to mix in new code. Therefore, it’s an often-used technique in Python to change the behavior of a class by using multiple inheritances. Contrary to C++, it is legal in Python to have more than one method definition in a class hierarchy. Python uses that method that is first in the Method Resolution Order (MRO).
You can implement mixins in C++ by using CRTP. A prominent example is the class
std::enable_shared_from this and, therefore, CRTP applied.
By using the class,
std::enable_shared_from_this you can create objects that return a
std::shared_ptr to itself. You must derive your class public from (line 1) to get it. Now, your class
MySharedClass has a member function
shared_from_this (line 2) for creating
std::shared_ptr to its objects. The call
shareMe->getShared() (line 3) creates a new smart pointer. The member function
getShared internally uses the function
shared_from_this (line 2). The following screenshot shows the creation of the shared pointer.
To learn more about smart pointers, read my previous posts: smart pointers.
How do mixin classes work in C++? Let me introduce a typical use case.
Extending a Class with all Relational Operators
Imagine you want to implement all six comparison operators for your data type. (Of course, with C++20, the compiler can auto-generate them: C++20: The Three-Way Comparison Operator). So far, you have only implemented the smaller operator (<). You know that you can derive all other five comparison operators (
<=, >, >=, == , and
!=) from the smaller operator. Applying this idea and using CRTP save you many keyboard strokes.
Man implemented the smaller operator (lines 1 and 2). For simplicity, I only use the class
Man in my argumentation. Man is
public derived from the class
Relational<Man> (line 3) using CRTP. The class
Relational supports the five missing relational operators (
<=, <,>=, ==, and
!=). The five relations operators are mapped onto the less operator of Man (line 2).
Honestly, I like the name mixins for this idiom. The class
Relational mixes the remaining relational operators into the class
The characteristic of CRTP is that a class
Derived derives from a class template
Derived as a template argument:
How can you ensure that you are not erroneously derived the wrong class
Base<Derived> such as in line 2?
The trick is straightforward: make the constructor of
Base has a private default constructor (line 1). Only the class
Base itself or the friend
Derived (line 2) can invoke the default constructor. Consequentially, the call
Derived2 d2 (line 3) fails because
Derived2 it is derived from
Base<Derived1>. Here is the error message from GCC:
The Curiously Recurring Template Pattern (CRTP) is not easy to understand but very powerful. The same holds for expression templates. Expression templates allow you to get rid of superfluous temporaries.
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, and Marco Parri Empoli.
Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.
|My special thanks to Embarcadero|
|My special thanks to PVS-Studio|
|My special thanks to Tipi.build|
|My special thanks to Take Up Code|
I’m happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
- Embedded Programmierung mit modernem C++ 12.12.2023 – 14.12.2023 (Präsenzschulung, Termingarantie)
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
- C++ – The Core Language
- C++ – The Standard Library
- C++ – Compact
- C++11 and C++14
- Concurrency with Modern C++
- Design Pattern and Architectural Pattern with C++
- Embedded Programming with Modern C++
- Generic Programming (Templates) with C++
- Clean Code with Modern C++
- Phone: +49 7472 917441
- Mobil:: +49 176 5506 5086
- Mail: schulung@ModernesCpp.de
- German Seminar Page: www.ModernesCpp.de
- Mentoring Page: www.ModernesCpp.org
Modernes C++ Mentoring,