为什么 std::uniform_int_distribution<IntType>::operator() 不是 const 的?

9

据我理解,当用于生成随机数时,分布应该保持不变。例如,对于均匀分布,其最小值/最大值在生成随机数时不应更改。那么为什么operator()不是const的呢?


2
某些发行版会一次计算多个随机数并将其缓存以加快进程速度。但它们也可以使用mutable - Marc Glisse
1
@MarcGlisse 有哪些发行版可以这样做,它是如何工作的?它不可能知道下一次将被调用的生成器是哪个。即使它能够 - 从一个精心种植的生成器中选择多个数字也是不好的 :-) - Ted Lyngmo
1
在libstdc++中,正态分布一次计算两个随机数。下次调用时,它不会使用传递给它的生成器。 - Marc Glisse
@TedLyngmo 就算是标准的伪随机数生成器,也要在N次调用后给出特定的值,但所有标准分布都仅由概率函数定义。只要满足这个条件,除了必须存在的函数和类型定义外,就没有其他要求了。如果需要可移植性,则需要自己编写或从库中获取并专门使用它。 - NathanOliver
谢谢 - 我查看了gcc 9的uniform_int_distribution头文件,没有找到关于它保持状态的任何信息,重置实现为void reset() { }。我唯一发现它多次调用PRNG的情况是如果需要进行上下缩放 - 但那里有太多下划线,让我感到头疼,所以我可能错过了一些内容。 - Ted Lyngmo
1个回答

9

min()max()不会改变,但分布可能包含帮助生成下一个值的状态。如果operator()const,那么没有修改此状态的方法而又需要保证对象线程安全,这将是昂贵的。提供这种保证可能会很耗费资源,而分布被设计为轻量级。


"const => 线程安全": 如果他们愿意,他们可以在标准文档中记录这个特定函数不需要是线程安全的。关于const和线程安全的一般措辞只是默认情况,当没有指定特定行为时使用。尽管如此,保持一致并省略const确实很方便。 - Marc Glisse
1
@MarcGlisse 他们可以这样做,但那将违反C++试图使用的最小惊讶原则,尽管结果参差不齐。 - NathanOliver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接