When they were first introduced in the language, type traits, defined in header <type_traits>,
required to use nested types
(with ::type
) or nested values (with ::value
) to access the result of the trait. Since then, the language introduced
templated alias declaration and variable templates that allow to define traits in a more direct and readable way.
Even if the old variant still exists, the new one, which uses _t
(C++14) and _v
(C++17) suffixes as discriminant, should
be preferred.
Noncompliant code example
template<class T>
void f(T t) {
static_assert (std::is_arithmetic<T>::value); // Noncompliant
using rawType = std::remove_cv<T>::type; // Noncompliant
}
Compliant solution
template<class T>
void f(T t) {
static_assert (std::is_arithmetic_v<T>); // Compliant, C++17
using rawType = std::remove_cv_t<T>; // Compliant, C++14
}