我正在了解这个图书馆,它在很多方面改进了旧兰特和品牌。但是对于rand来说,很明显只有一个随机数生成器在使用rand时被调用和更新,无论你的程序在哪里。通过新的方式,我不确定如何有效地模仿这种行为并且具有良好的风格。例如,如果我想要一个骰子滚动,并在主程序中编写一个在线示例,我用这样的方法写一个对象:
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);
}
}
这看起来很糟糕,因为每次你想要掷骰子时都会重新创建引擎。这是一个有点人为的案例,但在一个大型程序中,你将不得不将随机数生成器的声明放在某个地方。作为第一次尝试使用我只想让所有随机数都有一个生成器,就像过去一样。实现这一目标的最好方法是什么?在线简单可用的示例都直接写入主程序,因此他们不回答这个基本问题。 我想不出任何看起来像用大锤敲打坚果的东西。任何帮助都会很棒。
答案 0 :(得分:4)
对于这样一个微不足道的案例,我会把它们全部static
并且不要太担心它。肯定会返回int
!
int getDiceRoll() {
static std::random_device rd;
static std::default_random_engine gen(rd());
static std::uniform_int_distribution<int> dis(1, 6);
return dis(gen);
}
答案 1 :(得分:3)
你可以将它全部包装在这样的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
答案 2 :(得分:2)
我没有编译,所以可能会出现一些语法错误......但你明白了这个想法。
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;
};