The type-traits library supports type checks, type comparisons, and type modifications at compile time. Right! Today, I write about type modifications at compile time.
The Type-Traits Library
Type modification is the domain of template metaprogramming and, therefore, for the type-traits library.
Maybe, you are curious about what is possible at compile time. A lot! Here are the most exciting metafunctions:
To get an int from int or const int, you must ask for the type with ::type.
Since C++14, you can use _t to get the type, such as for std::remove_const_t:
To get an idea of how valuable these metafunctions from the type-traits library are, here are a few use cases. Here is std::move in one line.
- remove_reference: std::move and std::forward uses this function to remove the reference from its argument.
- decay: std::thread applies std::decay to its arguments. Their usage includes the function f a thread executes on its arguments args. Decay means that implicit conversions from array-to-pointer, and function-to-pointer is performed, and const/volatile qualifiers and references are removed.
- enable_if: std::enable_if is a convenient way to use SFINAE. SFINAE stands for Substitution Failure Is Not An Error and applies during overload resolution of a function template. When substituting the template parameter fails, the specialization is discarded from the overload set but causes no compiler error. std::enable_if is heavily used in std::tuple.
- conditional: std::conditional is the ternary operator at compile time.
- common_type: std::common_type determines the common type of a group of types.
- underlying_type: std::underlying_type determines the type of an enum.
Maybe, you are not convinced about the benefit of the type traits library. Let me end my story with the type-traits with their primary goals: correctness and optimization.
Correctness means, on one hand, that you can use the type-traits libraries to implement concepts such as Integral, SignedIntegral, and UnsignedIntegral.
But it also means you can use them to make your algorithm safer. I used in my previous post, More and More Safe, the functions std::is_integral, std::conditional, std::common_type, and std::enable_if from the type-traits library to make the generic gcd algorithm successively safer.
To get a better idea of the post More and More Safe , here is the starting point of my generic gcd algorithm.
The output of the program shows two issues.
First, double (line 1) and the C-String (line 2) fail in the modulo operator. Second, using an integer and a long (line 3) should work. Both issues can be elegantly solved with the type-traits library.
The type-traits are not only about correctness it’s also about optimization.
The key idea of the type-traits library is relatively straightforward. The compiler analysis the used types and makes, based on this analysis decision about which code should run. In the case of the algorithm std::copy, std::fill, or std::equal of the standard template library, the algorithm is applied to each element of the range one-by-one or the entire memory. In the second case, C functions such as memcmp, memset, memcpy, or memmove are used, making the algorithm faster. The slight difference between memcpy and memmove is that memmove can deal with overlapping memory areas.
The following three code snippets from the GCC 6 implementation clarify one point: The type-traits library checks help generate more optimized code.
Lines 1, 2, and 3 show that the type-traits library is used to generate more optimized code. My post Type-Traits: Performance Matters, gives you more insight and has performance numbers with GCC and MSVC.
With constexpr, programming at compile time escapes its expert niche and becomes a mainstream technique. constexpr is programming at compile time with the typical C++-Syntax.
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,