Background
I'm building a discrete selector, e.g. given a sequence, it picks randomly one element with probability according to given weights. You can think of it as a pair of PredefinedRandomGenerator
and std::discrete_distribution
. I'd like the selector to be portable, and provide sane entropy. It will not be used in cryptographic context, I just want better randomness (sorry if I messed up terminology here).
Problem
std:random_device
on MinGW on Windows always yields the same number. As a workaround, I use
//assume using namespace std::chrono
std::seed_seq seq{std::random_device{}(),
duration_cast<nanoseconds>(system_clock::now()).count(),
42};
The problem is that the constructor of PredefinedRandomGenerator
expects lvalue-reference, so I cannot initialize it in member initializer list as follows:
template <typename InputIterator>
discrete_selector(InputIterator weights_first,
InputIterator weights_last):
generator(std::seed_seq{/*...*/}),
distribution(weights_first, weights_last)
{}
So now there is at least one source of more or less random number.
What I tried
//somewhere in namespace details
std::seed_seq& get_new_sequence()
{
static std::unique_ptr<std::seed_seq> sequence;
sequence = std::make_unique<std::seed_seq>(std::random_device{}(),
duration_cast<nanoseconds>(system_clock::now()).count(),
42);
return *sequence;
}
The above should work, but I believe there should be a better way of doing that.
Side question
Why does constructor take the std::seed_seq
by lvalue reference? It could at least use rvalue-reference.
Aucun commentaire:
Enregistrer un commentaire