Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

template parameter incompatible with declaration

I have a function that should generate a random integer or a random floating point value.
For that I want to use concepts.

Since integers and floating points need different distributions, namely std::uniform_int_distribution and std::uniform_real_distribution respectively, I use a separate struct to select the correct type – also with a concept overload.
The "selector" looks like this:

template<std::integral I>
struct distribution_selector {
    using type = std::uniform_int_distribution<I>;
};

template<std::floating_point F>
struct distribution_selector {
    using type = std::uniform_real_distribution<F>;
};

You see that I use using to have a different type selected, depending on whether I use an integer type or a floating point type.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Now my actual function:

template<typename T = float, random_mode quality = random_mode::high_quality>
requires std::integral<T> || std::floating_point<T>
constexpr inline T rand(random& r, T min = std::numeric_limits<T>::min(), T max = std::numeric_limits<T>::max()) {
    using distribution = distribution_selector<T>::type;
    if constexpr(quality == random_mode::low_quality) {
        return distribution<T>(min, max)(r.low_quality_engine);
    } else {
        return distribution<T>(min, max)(r.high_quality_engine);
    }
}

demo

I receive the following errors (msvc):

Error (active)  E3244   template constraint not satisfied   Runtime C:\...\rand.h   35      type constraint failed for "float"
atomic constraint evaluates to false
          detected during instantiation of "T raid::rand(raid::random &r, T min = std::numeric_limits<T>::min(), T max = std::numeric_limits<T>::max()) [with T=float, quality=raid::random_mode::low_quality]" at line 34
Error (active)  E0519   type "distribution" may not have a template argument list   Runtime C:\...\rand.h   37      detected during instantiation of "T raid::rand(raid::random &r, T min = std::numeric_limits<T>::min(), T max = std::numeric_limits<T>::max()) [with T=float, quality=raid::random_mode::low_quality]" at line 34

What am I missing?

>Solution :

Use the concepts in the specialization but not in the declaration of the primary template.
Also, distribution is not a template, its type is determined at its context.

template <typename T>
struct distribution_selector;

template<std::integral I>
struct distribution_selector<I> {
    using type = std::uniform_int_distribution<I>;
};

template<std::floating_point F>
struct distribution_selector<F> {
    using type = std::uniform_real_distribution<F>;
};

template<typename T = float, random_mode quality = random_mode::high_quality>
requires std::integral<T> || std::floating_point<T>
constexpr inline T rand(random& r, T min = std::numeric_limits<T>::min(), T max = std::numeric_limits<T>::max()) {
    using distribution = distribution_selector<T>::type;
    if constexpr(quality == random_mode::low_quality) {
        return distribution(min, max)(r.low_quality_engine);
    } else {
        return distribution(min, max)(r.high_quality_engine);
    }
}

Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading