Sprout.Random で次の乱数を取得する
constexpr 時の Sprout.Random は内部の値が変更できない為、標準ライブラリ
ではどうやって次の乱数値を取得するのかというと operator() を再度呼び出します。
[ソース]
#include <sprout/random.hpp> #include <iostream> // n 回分 () の呼び出し template<typename Gen> constexpr auto call_n(Gen&& gen, int index) ->decltype(*gen()){ return index <= 0 ? *gen() : call_n(gen(), index-1); } int main(){ static constexpr sprout::hellekalek1995 engine; static_assert(engine() == 2110608584, ""); static_assert(engine()() == 239248507, ""); static constexpr sprout::uniform_int_distribution<int> dist1(100, 999); static_assert(dist1(engine)() == 200, ""); static_assert(dist1(engine)()() == 566, ""); static_assert(dist1(engine)()()() == 255, ""); static_assert(dist1(engine)()()()() == 175, ""); static_assert(call_n(dist1(engine), 0) == 200, ""); static_assert(call_n(dist1(engine), 1) == 566, ""); static_assert(call_n(dist1(engine), 2) == 255, ""); static_assert(call_n(dist1(engine), 3) == 175, ""); return 0; }
おもしろいですね。
(というか考えていたような呼び出し方が既に実装されていた感じ。
あと constexpr ではないけど const じゃない operator() を呼び出した場合は内部の値を変更して標準ライブラリと同じような振る舞いにすれば実行時乱数エンジンとしても使用できるんじゃないかと思った。
……振る舞いが異なるしややこしいかな?