2017-12-05 15 views
2

以下のコードを実行すると、arrの前半は後半になります。どうして?私は様々な種子を試しました。 std::chrono::system_clock::now().time_since_epoch().count()。ありがとう。std :: uniform_real_distribution同じ乱数を再生成

#include <algorithm> 
#include <iostream> 
#include <random> 


template<typename DistributionType> 
class Rng 
{ 
public: 
     template<typename ...Args> 
     Rng(Args&&... args) : dist(args...) { } 

     typename DistributionType::result_type operator()() 
     { 
       return dist(gen); 
     } 

private: 
     std::default_random_engine gen; 

     DistributionType dist; 
}; 


class UniformRealRng : public Rng<std::uniform_real_distribution<double>> 
{ 
public: 
     UniformRealRng(const double a, const double b) : Rng(a, b) { } 
}; 

int main() 
{ 
     constexpr int sz = 6; 
     constexpr int k = sz/2; 
     double arr[sz]; 

     UniformRealRng rng(0.0, 1.0); 
     std::generate(arr, arr + k, rng); 
     std::generate(arr + k, arr + sz, rng); 

     for (int i = 0; i < sz; ++i) 
     { 
       std::cout << arr[i]; 
     } 
     std::cout << "\n"; 
} 

答えて

0

あなたの答えは、事実上正しいが、それは問題を解決していません。 誤って(?)乱数ジェネレータをコピーしようとすると、コンパイルエラーが発生するだけです。

std::reference_wrapperライブラリ機能を使用すると、コードが意味的に正しいことが分かります。

std::generate(arr, arr + k, std::ref(rng)); 
    std::generate(arr + k, arr + sz, std::ref(rng)); 

このように、基本的には引数を参照渡しする必要があります。 幸いにも参照ラッパーはoperator()をオーバーロードします。したがって、追加のコードなしでジェネレーターに使用することができます。

完全なコード:

#include <algorithm> 
#include <iostream> 
#include <random> 
#include <functional> //ref 

template<typename DistributionType> 
class Rng 
{ 
public: 
     template<typename ...Args> 
     Rng(Args&&... args) : dist(args...) { } 
//  Rng(Rng&)    = delete; // this is not needed for it to work 
//  Rng& operator=(Rng&) = delete; // you MAY want to copy the generator 
     typename DistributionType::result_type operator()() 
     { 
       return dist(gen); 
     } 

private: 
     std::default_random_engine gen; 

     DistributionType dist; 
}; 


class UniformRealRng : public Rng<std::uniform_real_distribution<double>> 
{ 
public: 
     UniformRealRng(const double a, const double b) : Rng(a, b) { } 
}; 

int main() 
{ 
     constexpr int sz = 6; 
     constexpr int k = sz/2; 
     double arr[sz]; 

     UniformRealRng rng(0.0, 1.0); 
     std::generate(arr, arr + k, std::ref(rng)); 
     std::generate(arr + k, arr + sz, std::ref(rng)); 

     for (int i = 0; i < sz; ++i) 
     { 
       std::cout << arr[i]; 
     } 
     std::cout << "\n"; 
} 
3

std::generate値によって、その第三の引数を取り、そうrngがコピーされていました。

安全のために、一つはコピーを削除することができます:

Rng(Rng&)    = delete; 
Rng& operator=(Rng&) = delete; 
関連する問題