We have uniform_int_distribution
and uniform_real_distribution
, wouldn't it be possible to have an encompassing uniform_distribution
, which specializes in float/double and int/..., when specified?
AFAIU, the comments above by @user877329 and @revolver_ocelot explain this correctly, and the other answer is completely wrong.
It is wrong to unify the interfaces of uniform_int
and uniform_real
, not because they are implemented differently (which can be solved via template specialization), but because the interfaces mean different things.
Suppose we unify the interfaces (using a variation of the suggestion in the other answer), like so:
template <typename T>
using uniform_distribution =
typename std::conditional<
std::is_integral<T>::value,
std::uniform_int_distribution<T>,
std::uniform_real_distribution<T>
>::type;
Then if we define uniform_distribution<some_type> u(0, 9)
, the meaning is very different:
if some_type
is integral, then u will output 9 approximately 1/10ths of the time.
if some_type
is not, then u
will never output 9.
The following code (whose output is true
and then false
) illustrates this:
#include <random>
#include <iostream>
#include <type_traits>
template <typename T>
using uniform_distribution =
typename std::conditional<
std::is_integral<T>::value,
std::uniform_int_distribution<T>,
std::uniform_real_distribution<T>
>::type;
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
{
uniform_distribution<int> u(0, 9);
bool over_found = false;
for(size_t i = 0; i < 99999; ++i)
over_found = over_found || u(gen) >= 9;
std::cout << std::boolalpha << over_found << std::endl;
}
{
uniform_distribution<float> u(0, 9);
bool over_found = false;
for(size_t i = 0; i < 99999; ++i)
over_found = over_found || u(gen) >= 9;
std::cout << std::boolalpha << over_found << std::endl;
}
}
This code illustrates that writing generic code using this class is dangerous. For example, if you'd write a generic function calculating a histogram of the results in the subranges: [0, 1), [1, 2), ..., [8, 9), the results would be incompatible.
As @revolver_ocelot points out, the standard library's [inclusive-begin, exclusive_end) convention cannot be used for uniform integers (because it would be impossible to specify a uniform integer random number generator generating also the maximum uint value), making this an exceptional signature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With