Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

templates

I am going to write a template to generate a vector of random data. The problem is std::uniform_int_distribution only accepts integer type, and std::uniform_real_distribution for float type. I want to combine both. Here is my code.

#include <vector>
#include <random>
#include <algorithm>
#include <iterator>
#include <functional>

template<typename T>
std::vector<T> generate_vector(size_t N, T lower = T(0), T higher = T(99)) {
    // Specify the engine and distribution. 
    if constexpr (std::is_integral<T>) {
    std::uniform_int_distribution<T> distribution(lower, higher);
    }
    else if constexpr (std::is_floating_point<T>) {
    std::uniform_real_distribution<T> distribution(lower, higher);
    }
    std::mt19937 engine; // Mersenne twister MT19937
    auto generator = std::bind(distribution, engine);
    std::vector<T> vec(N);
    std::generate(vec.begin(), vec.end(), generator);
    return vec;

I am confusing how to implement statements within if conditions. Integer type should include:short, int, long, long long, unsigned short, unsigned int, unsigned long, or unsigned long long. Float type includes float, double, or long double.

Any help suggestion?

like image 553
ted930511 Avatar asked Jan 11 '18 04:01

ted930511


People also ask

How do you check if a number is an integer C++?

Apply isdigit() function that checks whether a given input is numeric character or not. This function takes single argument as an integer and also returns the value of type int.

What is Typename in C++ template?

" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.

How do you use template arguments in C++?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)


1 Answers

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.

like image 143
Brandon H. Gomes Avatar answered Oct 14 '22 09:10

Brandon H. Gomes