所以我有一个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);
}
Run Code Online (Sandbox Code Playgroud)
什么是我可以改变(通过另一个函数或其他方式)分布的上限的最佳方式?
(也愿意就其他风格问题提出建议)
在Stackoverflow上,有很多关于从a-priory未知范围生成均匀分布的整数的问题.例如
典型的解决方案是这样的:
inline std::mt19937 &engine()
{
thread_local std::mt19937 eng;
return eng;
}
int get_int_from_range(int from, int to)
{
std::uniform_int_distribution<int> dist(from, to);
return dist(engine());
}
Run Code Online (Sandbox Code Playgroud)
鉴于分布应该是一个轻量级对象并且没有性能问题需要多次重新创建它,看起来即使是简单的分发也可能很好并且通常会有一些内部状态.
所以我想知道是否通过不断重置它来干扰分布如何工作(即在每次调用时重新创建分布get_int_from_range)我得到了正确分布的结果.
Pete Becker和Steve Jessop之间进行了长时间的讨论,但没有最后的说法.在另一个问题中(我应该保留随机分布对象实例还是可以随时重新创建它?)内部状态的"问题"似乎并不重要.
C++标准是否对此主题做出了任何保证?
以下实现(来自N4316 - std :: rand替换)是否更可靠?
int get_int_from_range(int from, int to)
{
using distribution_type = std::uniform_int_distribution<int>;
using param_type = typename distribution_type::param_type;
thread_local std::uniform_int_distribution<int> dist;
return dist(engine(), param_type(from, to));
}
Run Code Online (Sandbox Code Playgroud)
编辑
这重用了分发的可能的内部状态,但它很复杂,我不确定它是否值得麻烦:
int get_int_from_range(int from, int to)
{
using …Run Code Online (Sandbox Code Playgroud)