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