Type-Traits Overview
Understand how C++ type-traits enable compile-time type analysis, optimize algorithm selection based on types, and perform type transformations and checks. Learn the roles of primary and composed type categories, type comparisons, and transformations in improving code correctness and performance.
We'll cover the following...
Type-Traits Library
Type-traits enable type checks, type comparisons, and type modifications at compile-time.
Below are some applications of template metaprogramming:
- Programming at compile-time
- Programming with types and values
- Compiler translates the templates and transforms it in C++ source code
We need to add a type_traits library in the header to enable all the functions present in the library.
#include <type_traits>
Type-Traits: Goals
If you look carefully, you’ll see that type-traits have a significant optimization potential. In the first step, type-traits help to analyze the code at compile-time and in the second step, to optimize the code based on that analysis. How is that possible? Depending on the type of variable, a faster variant of an algorithm will be chosen.
Optimization
- Code that optimizes itself. Depending on the type of a variable another code will be chosen.
- Optimized version of
std::copy,std::fill, orstd::equalis used so that algorithms can work on memory blocks. - The optimized version of operations happens on all the elements in a container in one step and not on each element individually.
Correctness
- Type checks will be performed at compile-time.
- Type information, together with
static_assert, defines the requirements for the code. - With the concepts in C++20, the correctness aspect of the type-traits becomes less important.
Type Checks
C++ has 14 primary type categories. They are complete and orthogonal. This means, that each type is a member of exactly one type category. The check for the type categories is independent of the type qualifiers const or volatile.
Let’s have a look at these categories syntactically:
We can divide the type-traits into smaller sets for simplicity.
- Primary type category (
::value)
std::is_pointer<T>,
std::is_integral<T>,
std::is_floating_point<T>
- Composed type category (
::value)
std::is_arithmetic<T>,
std::is_object<T>
- Type comparisons (
::value)
std::is_same<T,U>,
std::is_base_of<Base,Derived>,
std::is_convertible<From,To>
- Type transformation (
::type)
std::add_const<T>,
std::remove_reference<T>
std::make_signed<T>,
std::make_unsigned<T>
- Others (
::type)
std::enable_if<bool,T>
std::conditional<bool,T,F>
std::common_type<T1, T2, T3, ... >
The above-mentioned functions, from the type-traits, give only a rough idea of their power. To learn more about type checks, click here. The above-mentioned functions are available on the given link with more detail.
We have implemented is_same and remove_const in the namespace rgr. This corresponds to the type-traits library. For simplicity reason, we use the static constants std::false_type and std::true_type (lines 10 and 13). Thanks to the base class std::false_type, the class template has a member value. Respectively for std::true_type. The key observation of the class template is_same is to distinguish the general template (lines 9 and 10) from the partially specialized template (line 12 and 13). The compiler will use the partially specialized template if both template arguments have the same type. The partially specialized template, as opposed to the general template, has only one type parameter.
Our reasoning for the class template remove_const is similar. The general template returns, via its member type, exactly the same type; the partially specialized template returns the new type after removing the const property (line 22). The compiler will choose the partially specialized template if its template argument is const.
The rest is quickly explained. In lines 31 and 32, we used the functions of the type-traits library and our own versions. We declared a typedef mydouble (line 34), a type myString (line 37), and a type myInt (line 40). All types are non-constant.
In the next lesson, we’ll study type-traits correctness and their optimization with the help of an example.