How to use condition to check if typename T is integer type of float type in C++

In a pre-C++17 compiler, you can use template specialization to implement the if-else logic.

// Declare a class template
template <bool is_integral, typename T> struct uniform_distribution_selector;

// Specialize for true
template <typename T> struct uniform_distribution_selector<true, T>
{
   using type = typename std::uniform_int_distribution<T>;
};

// Specialize for false
template <typename T> struct uniform_distribution_selector<false, T>
{
   using type = typename std::uniform_real_distribution<T>;
};


template<typename T>
std::vector<T> generate_vector(size_t N, T lower = T(0), T higher = T(99))
{
   // Select the appropriate distribution type.
   using uniform_distribution_type = typename uniform_distribution_selector<std::is_integral<T>::value, T>::type;

   uniform_distribution_type distribution(lower, higher);
   std::mt19937 engine;
   auto generator = std::bind(distribution, engine);
   std::vector<T> vec(N);
   std::generate(vec.begin(), vec.end(), generator);
   return vec;
}

As Justin points out in his comment it is simple enough to use an if constexpr block in the following way:

#include <type_traits>

if constexpr (std::is_integral_v<T>) {  // constexpr only necessary on first statement
    ...
} else if (std::is_floating_point_v<T>) {  // automatically constexpr
    ...
}

This is only available C++17. See the C++ references for more information on compile-time type information:

if constexpr (since C++17)

<type_traits> (since C++11)

constexpr specifier (since C++11)

Constant Expressions in general.

Tags:

C++

Templates