37122


C++で乱数の配列を生成しようとしています。

以下のようなコードを書いてみたのですが、配列の内容が毎回同じになってしまいます。generate_array() の呼び出しで rng
の内部状態は更新されるはずだと思うのですが、実際にはそうなっていないように見えます。なぜこのような挙動になるのでしょうか?

[code]

    #include <algorithm>
    #include <functional>
    #include <random>
    #include <iostream>
    
    using namespace std;
    
    default_random_engine rng;
    
    void print_array(const int* ary, size_t n)
    {
        for(size_t i = 0; i < n-1; ++i)
            cout << ary[i] << (i==n-1 ? "" : " ");
        cout << "\n";
    }
    
    void generate_array(int* ary, size_t n)
    {
        uniform_int_distribution<int> dist;
        auto gen = bind(dist,rng);
        generate(ary, ary+n, gen);
    }
    
    int main()
    {
        random_device rd;
        rng.seed(rd());
    
        constexpr int N = 10;
        int ary[N];
    
        fill(ary, ary+N, 0);
        print_array(ary, N);
    
        generate_array(ary, N);
        print_array(ary, N);
        generate_array(ary, N);
        print_array(ary, N);
    
        return 0;
    }
    
[/code]

wandbox上での実行結果を示します:  
<https://wandbox.org/permlink/RVHGTKCvVtfmS04F>

なお、`bind(dist,rng)` の直前に `dist(rng)` の呼び出しを入れるとなぜか意図した通りの動作になります:  
<https://wandbox.org/permlink/LwQjAjxhDJBqDvuI>


CC BY-SA 3.0
2017-08-11T12:46:37.230
37121
2017-08-11T13:17:21.330
2017-08-11T13:10:09.603
76
24838
question
c++ c++11
std::generate() で生成した乱数が毎回同じになるのはなぜ?


`std::bind`はオブジェクトをコピーします。状態をコピーされた乱数生成器は同じ乱数を生成します。

コピーを回避するためには`bind(dist, ref(rng))`と明示的に参照を渡してください。


CC BY-SA 3.0
2017-08-11T13:17:21.330
37122
2017-08-11T13:17:21.330
4236
37121
answer