Based on this question, I have made a simple program to print a sequence of random numbers. The program seems to run fine, but I would like to know if my implementation is correct and how I can improve it.
#include <random>
#include <array>
#include <algorithm>
#include <functional>
#include <iostream>
template<class T = std::mt19937, std::size_t N = T::state_size>
auto randomEngine() -> typename std::enable_if_t<!!N, T>
{
std::array<typename T::result_type, N> seed_data;
thread_local static std::random_device source;
std::generate(std::begin(seed_data), std::end(seed_data), std::ref(source));
std::seed_seq seeds(std::begin(seed_data), std::end(seed_data));
thread_local static T seeded_engine(seeds);
return seeded_engine;
}
template<typename T>
T random(T min, T max)
{
static_assert(std::is_integral<T>::value || std::is_floating_point<T>::value, "!");
using UniformInt = std::uniform_int_distribution<T>;
using UniformReal = std::uniform_real_distribution<T>;
using DistType = std::conditional_t<std::is_integral<T>::value, UniformInt, UniformReal>;
static auto RandomEngine = randomEngine();
DistType uniformDistribution(min, max);
return uniformDistribution(RandomEngine);
}
int main()
{
for (auto i = 0u; i < 16; ++i)
std::cout << random(0u, 15u) << ' ';
}
mt19937
correctly (I think), but it seems like such a waste of effort compared to just using a good RNG like from the PCG family, which also happens to handle much of this nonsense for you. \$\endgroup\$