Thanks to templates, there are new ways of software design. Policies and traits are two commonly used idioms in C++.
Policy and traits are often used in one sentence. Let me start with policies.
A policy is a generic function or class whose behavior can be configured. Typically, there are default values for the policy parameters.
std::unordered_map exemplifies this.
This means each container has a default allocator for its elements depending on
T (line 1) or
std::pair<const Key, T> (line 2). Additionally,
std::unorderd_map has a default hash function (line 3) and a default equal function (4). The hash function calculates the hash value based on the key, and the equal function deals with collisions in the buckets. My previous post, “Hash Functions” gives you more information about
Let me use a user-defined data type
MyInt as a key in a
The compilation fails pretty wordily because
MyInt does not support the hash function or the equal function.
Now, the policy kicks in. You can replace the policy parameters. The following class
MyInt can, therefore, be used as a key in a
I implemented the hash function (line 1) and the equal function (line 2) as a function object and overloaded, for convenience reasons, the output operator (line 3). Line 4 creates out of all components a new type
MyIntMap that uses
MyInt as key. The following screenshot shows the output of the instance
There are two typical ways to implement policies: composition and inheritance.
The following class
Message uses composition to configure its output device during compile time.
The class Message has the template parameter OutputPolicy (line 1) as policy. A call of its member function
write delegates directly to its member
outPolicy (line 2). You can create two different
Message instances (lines 3 and 4). One writing to count (line 5), and one writing to a file (line 6).
The screenshot shows the write operation to
cout and the file
The inheritance-based implementation is quite similar to the composite based in the file
policyComposition.cpp. The main difference is that the composite-based implementation has the policy, but the inheritance-based implementation derives from its policy.
Instead of the previous implementation of the class
Message, this one derives from its template parameter privately and introduces the private inherited
Composition or Inheritance
In general, I prefer composition over inheritance. In general, but for a policy-based design, you should consider inheritance.
OutputPolicy is empty, you can benefit from the so-called empty base class optimization. Empty means that
OutputPolicy has no non-static data members and no non-empty base classes. Consequentially
OutputPolicy does not add anything to the size of
Message. On the contrary, when
Message has the member
OutputPolicy adds at least one byte to the size of
Message. My argument may not sound convincing, but often a class uses more than one policy.
Traits are class templates that pull properties out of a generic type. I will write more about them in my next post.
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, and Bhavith C Achar.
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,