【发布时间】:2020-08-25 16:01:24
【问题描述】:
对于单元测试,我实现了一个模拟随机数生成器。我相信这是UniformBitGenerator 的有效实现(模拟实际上使用google mock 来设置operator() 的返回,但它的行为相同)。
struct RNG
{
using result_type = size_t;
static result_type min() { return 0; }
static result_type max() { return std::numeric_limits<result_type>::max(); }
result_type operator()() { return max(); }
};
现在我使用这个模拟从std::uniform_int_distribution 在[a, b], a == b 范围内进行采样。我相信这是允许的,我发现here 对分布参数的唯一限制是b >= a。所以我希望下面的程序打印5。
int main()
{
auto rng = RNG();
auto dist = std::uniform_int_distribution<>(5, 5);
printf("%d\n", dist(rng));
return 0;
}
相反,它进入了 STL 内部的无限循环,反复从生成器中提取数字,但无法在指定范围内找到数字。我测试了不同版本的不同(当前)编译器(包括clang、gcc、icc)。 RNG::max 也可以返回其他值(例如 42),不会改变任何东西。
我正在测试的真实代码将随机索引绘制到可能只包含一个元素的容器中。检查这种情况很容易,但这种情况很少见,我想避免这种情况。
我是否遗漏了 STL 中的 RNG 规范中的某些内容?我会惊讶地发现所有编译器中都有一个错误......
【问题讨论】:
-
不错。对于
std::uniform_int_distribution<>(a, b);,如果a > b,行为未定义,但我不确定a == b。 -
如果您使用实际的随机数生成器,它是否有效?
-
RNG 的 min/max 函数不是 BitGenerator 概念所要求的 constexpr。
-
它确实适用于实际的随机数生成器,因为它不会重复返回它的最大值。
标签: c++ random language-lawyer std