Instantiate template function depending on assignment

Viewed 43

I have a function that returns a random number and is templated against ints and floats with concepts.

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>;
};

struct random {
    std::mt19937 engine;
};

template<typename T>
requires std::integral<T> || std::floating_point<T>
constexpr inline decltype(auto) rand(random& r, T min = std::numeric_limits<T>::min(), T max = std::numeric_limits<T>::max()) {
    using distribution = distribution_selector<T>::type;
    return distribution(min, max)(r.engine);

}

for ease of use, i want to omit the template argument for T depending on what I assign the result of the function to:

int main() {
    using namespace r;
    random r;
    int i = rand(r,0,2); // will call rand<int>, correct
    short s = rand(r,0,3); // will call rand<int>, but I want rand<short>
    double d = rand(r,0,6); // will also call rand<int>, but i want rand<double>
    double dd = rand<double>(r,0,6); // will of course call rand<double>
    return s;
}

Demo

Is that possible?

1 Answers

No, this is not Haskell, C++ cannot infer types of expressions based on the surrounding context.

What you can do though is infer the type of variable based on the initialization (it's not an assignment):

auto i = rand<int>(r,0,2);  // int i
auto s = rand<short>(r,0,3); // short s
auto d = rand<double>(r,0,6); // double d
auto dd = rand<double>(r,0,6); // double dd

Provided that rand returns the correct type.

Related