Manual distinction of types when given any type T

suggest change

When implementing SFINAE using std::enable_if, it is often useful to have access to helper templates that determines if a given type T matches a set of criteria.

To help us with that, the standard already provides two types analog to true and false which are std::true_type and std::false_type.

The following example show how to detect if a type T is a pointer or not, the is_pointer template mimic the behavior of the standard std::is_pointer helper:

template <typename T>
struct is_pointer_: std::false_type {};

template <typename T>
struct is_pointer_<T*>: std::true_type {};

template <typename T>
struct is_pointer: is_pointer_<typename std::remove_cv<T>::type> { }

There are three steps in the above code (sometimes you only need two):

  1. The first declaration of is_pointer_ is the default case, and inherits from std::false_type. The default case should always inherit from std::false_type since it is analogous to a “false condition”.
  2. The second declaration specialize the is_pointer_ template for pointer T* without caring about what T is really. This version inherits from std::true_type.
  3. The third declaration (the real one) simply remove any unnecessary information from T (in this case we remove const and volatile qualifiers) and then fall backs to one of the two previous declarations.

Since is_pointer<T> is a class, to access its value you need to either:

It is a good habit to provides “helper helper templates” that let you directly access the value:

template <typename T>
constexpr bool is_pointer_v = is_pointer<T>::value;

In C++17 and above, most helper templates already provide a _v version, e.g.:

template< class T > constexpr bool is_pointer_v = is_pointer<T>::value;
template< class T > constexpr bool is_reference_v = is_reference<T>::value;

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Metaprogramming:
* Manual distinction of types when given any type T

Table Of Contents
8 Arrays
11 Loops
39 Streams
41 Metaprogramming
51 Unions
56 Lambdas
60 SFINAE
62 RAII
67 Sorting
84 RTTI
87 Scopes
104 Profiling
107 Recursion
117 Iteration
125 Alignment
134 Semaphore
136 Debugging
139 Mutexes
142 decltype