読者です 読者をやめる 読者になる 読者になる

乱数の分布クラスはステートフルか?

C++

C++標準とBoostにある乱数の分布クラスは、一見ジェネレータの状態のみに依存し、分布クラスは状態を持たないように見えます。しかし、分布クラスのコンセプトでは、関数呼び出し演算子constメンバ関数であることは規定されていません。そのため、分布クラスは状態を持つことが許可されています。
そして実際、C++標準の全ての分布クラスは、関数呼び出し演算子が非constメンバ関数になっています。


Why are c++11 random distributions mutable?


上記StackOverflowの質問に対する回答では、GCC(libstdc++)のnormal_distributionで、状態がキャッシュのために使用されている、という調査結果が出ています。
今のところ、より良い乱数分布のために状態が必須となるような分布クラスの仕様および実装は見つかっていませんが、C++標準もBoostも、各分布クラスの関数呼び出し演算子の、状態変化に対する詳細な仕様を記載していないことから、乱数生成の際には、ジェネレータと分布クラス、両方をメンバ変数等に配置して、どちらも状態を持てるようにしておいたほうがいいかもしれません。


ちなみに、Boostでは、uniform_int_distributiondiscrete_distributionは、関数呼び出し演算子constになっていて、normal_distributionは状態を持ってはいませんでしたが、関数呼び出し演算子が非constになっていました。