所以我有一个Random对象:
typedef unsigned int uint32;
class Random {
public:
Random() = default;
Random(std::mt19937::result_type seed) : eng(seed) {}
private:
uint32 DrawNumber();
std::mt19937 eng{std::random_device{}()};
std::uniform_int_distribution<uint32> uniform_dist{0, UINT32_MAX};
};
uint32 Random::DrawNumber()
{
return uniform_dist(eng);
}我可以改变(通过另一个函数或其他方式)分布的上限的最好方法是什么?
(也愿意接受其他风格问题的建议)
发布于 2013-09-27 02:52:38
分布对象是轻量级的。当你需要一个随机数时,只需构造一个新的分布。我在游戏引擎中使用了这种方法,在基准测试之后,它可以与使用老的rand()相媲美。
此外,我问过如何改变GoingNative 2013 live stream的分发范围,标准委员会的成员Stephen T. Lavavej建议简单地创建新的分发版,因为这不应该是一个性能问题。
下面是我如何编写你的代码:
using uint32 = unsigned int;
class Random {
public:
Random() = default;
Random(std::mt19937::result_type seed) : eng(seed) {}
uint32 DrawNumber(uint32 min, uint32 max);
private:
std::mt19937 eng{std::random_device{}()};
};
uint32 Random::DrawNumber(uint32 min, uint32 max)
{
return std::uniform_int_distribution<uint32>{min, max}(eng);
}发布于 2013-09-27 03:33:07
您可以简单地使用param()方法创建一个std::uniform_int_distribution<uint32>::param_type并修改范围。您可以使用decltype来降低模板噪声:
decltype(uniform_dist.param()) new_range (0, upper);
uniform_dist.param(new_range);发布于 2013-09-27 02:54:53
在我的示例中,我将DrawNumber函数设置为public。您可以提供一个接受上限的重载,然后将新的uniform_int_distribution::param_type传递给uniform_int_distribution::operator()
可以使用与相应分布相同的参数来构造param_type。
来自N3337,§26.5.1.6/9 rand.req.dist
对于
D的每个构造函数,其参数与分布的参数相对应,P应具有相应的构造函数,满足相同的要求,并采用数量、类型和默认值相同的参数。此外,对于返回与分布参数对应的值的D的每个成员函数,P都应该有一个具有相同名称、类型和语义的相应成员函数。
其中D是随机数分布函数对象的类型,P是由D的关联param_type命名的类型
#include <iostream>
#include <random>
typedef unsigned int uint32;
class Random {
public:
Random() = default;
Random(std::mt19937::result_type seed) : eng(seed) {}
uint32 DrawNumber();
uint32 DrawNumber(uint32 ub);
private:
std::mt19937 eng{std::random_device{}()};
std::uniform_int_distribution<uint32> uniform_dist{0, UINT32_MAX};
};
uint32 Random::DrawNumber()
{
return uniform_dist(eng);
}
uint32 Random::DrawNumber(uint32 ub)
{
return uniform_dist(eng, decltype(uniform_dist)::param_type(0, ub));
}
int main()
{
Random r;
std::cout << r.DrawNumber() << std::endl;
std::cout << r.DrawNumber(42) << std::endl;
}https://stackoverflow.com/questions/19036141
复制相似问题