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.