[英]Vary range of uniform_int_distribution
So i have a Random object: 所以我有一个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);
}
What's the best way I can vary (through another function or otherwise) the upper bound of of the distribution? 什么是我可以改变(通过另一个函数或其他方式)分布的上限的最佳方式?
(also willing to take advice on other style issues) (也愿意就其他风格问题提出建议)
Distribution objects are lightweight. 分发对象是轻量级的。 Simply construct a new distribution when you need a random number.
当您需要随机数时,只需构建一个新的分布。 I use this approach in a game engine, and, after benchmarking, it's comparable to using good old
rand()
. 我在游戏引擎中使用这种方法,并且在基准测试之后,它与使用好的旧
rand()
相当。
Also, I've asked how to vary the range of distribution on GoingNative 2013 live stream, and Stephen T. Lavavej, a member of the standard committee, suggested to simply create new distributions, as it shouldn't be a performance issue. 此外,我已经询问如何改变GoingNative 2013直播流的分发范围,标准委员会成员Stephen T. Lavavej建议简单地创建新的发行版,因为它不应该是性能问题。
Here's how I would write your code: 以下是我编写代码的方法:
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);
}
You can simply create a std::uniform_int_distribution<uint32>::param_type
and modify the range using the param()
method. 您只需创建一个
std::uniform_int_distribution<uint32>::param_type
并使用param()
方法修改范围。 You can cut down the template noise with decltype
: 您可以使用
decltype
减少模板噪音:
decltype(uniform_dist.param()) new_range (0, upper);
uniform_dist.param(new_range);
I'm making the DrawNumber
function public
for my example. 我正在为我的例子
public
DrawNumber
函数。 You can provide an overload that takes an upper bound, and then pass a new uniform_int_distribution::param_type
to uniform_int_distribution::operator()
您可以提供一个占用上限的重载,然后将一个新的
uniform_int_distribution::param_type
给uniform_int_distribution::operator()
The param_type
can be constructed using the same arguments as the corresponding distribution. 可以使用与相应分布相同的参数来构造
param_type
。
From N3337, §26.5.1.6/9 [rand.req.dist] 来自N3337, §26.5.1.6/ 9 [rand.req.dist]
For each of the constructors of
D
taking arguments corresponding to parameters of the distribution,P
shall have a corresponding constructor subject to the same requirements and taking arguments identical in number, type, and default values.对于
D
参数的每个构造函数,该参数对应于分布的参数,P
应具有相应的构造函数,这些构造函数具有相同的要求并且在数量,类型和默认值方面具有相同的参数。 Moreover, for each of the member functions ofD
that return values corresponding to parameters of the distribution,P
shall have a corresponding member function with the identical name, type, and semantics.此外,对于返回对应于分布参数的值的
D
每个成员函数,P
应具有相同的成员函数,其具有相同的名称,类型和语义。
where D
is the type of a random number distribution function object and P
is the type named by D
's associated param_type
其中
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.