C ++ <random> random number generators in realistic programs
I am studying a library that greatly improves the old rand and shit. But with rand it’s clear that there is one and only one random number generator that gets called and updated whenever rand is used, wherever you are in your program. With the new way, I'm not sure how to effectively simulate this behavior and with a good style. For example, if I want to roll a die and, trying on online examples written in the main procedure, I write an object using this method:
class foo{
public:
float getDiceRoll(){
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> uniform_dist(1, 6);
return uniform_dist(e1);
}
}
It looks awful because the engine is re-created every time you want to roll the dice. This is a little far-fetched case, but in a large program you will have to place a random number generator declaration somewhere. As a first attempt to use, I just want there to be one generator for all random numbers, as in the old days. What is the best way to achieve this? Easily accessible online examples are all written directly in the main procedure, and therefore they do not answer this basic question. I can't think of anything that doesn't look like picking up a sledgehammer to crack a nut. Any help would be great.
class
:
#include <random>
#include <iostream>
/**
* (P)seudo (R)andom (N)umber (G)enerator
*/
template<typename Type = int>
class PRNG
{
// easier to use param_type
using param_type = typename std::uniform_int_distribution<Type>::param_type;
// store an instance of the generator/distribution in the class object
std::mt19937 gen;
std::uniform_int_distribution<Type> dis;
public:
// seed generator when creating
PRNG(): gen(std::random_device()()) {}
Type get(Type from, Type to)
{
// only need to create a light weigt param_type each time
return dis(gen, param_type{from, to});
}
};
int main()
{
PRNG<int> prng;
for(auto i = 0U; i < 10; ++i)
std::cout << "die roll " << i << ": " << prng.get(1, 6) << '\n';
}
:
die roll 0: 2
die roll 1: 6
die roll 2: 1
die roll 3: 5
die roll 4: 6
die roll 5: 3
die roll 6: 3
die roll 7: 6
die roll 8: 3
die roll 9: 2
I did not compile, so some syntax errors may occur ... but you get the idea, something like this.
class foo
{
public:
foo()
{
e1 = std::default_random_engine(rd());
uniform_dist = std::uniform_int_distribution<int>(1, 6);
}
int getDiceRoll()
{
return uniform_dist(e1);
}
private:
std::random_device rd;
std::default_random_engine e1;
std::uniform_int_distribution<int> uniform_dist;
};