2017-02-02 3 views
2

У меня есть класс, содержащий ГСЧ:Правильная копия ГСЧ в C++

class Sampler{  
private: 
    std::random_device rd_; 
    std::mt19937 gen_; 

public: 
    Sampler(); 
    double sample(); 
}; 

Класс инициализируется следующим образом:

Sampler::Sampler() : 
        gen_(rd_()) 
{} 

Моя проблема заключается в том, что я хочу использовать этот класс (функция-член sample()) внутри другого класса, но я не могу скопировать класс, потому что невозможно скопировать std::random_device (конструктор копирования удален, так как в противном случае будут созданы одинаковые случайные числа).

class Foo{ 
private: 
    Sampler s_; 

public: 
    Foo(Sampler); 

}; 

И потом:

Foo::Foo(Sampler s) : 
     s_(s) // does not work 
{} 

В то время как это делает общий смысл я удивляюсь, как можно было бы реализовать это для того, чтобы заставить его работать. Я читал, что одной из возможностей было бы создать правильный конструктор копирования, чтобы каждый раз, когда копия была сделана, он получает семя с новым семенем, но я не знаю, как это сделать.

+0

Вам нужны еще случайные числа, сгенерированные в 'Foo', что в экземпляре' Sampler'? Если нет - почему бы не хранить ссылку/указатель (умный указатель)? – ForEveR

+2

Почему 'random_device' даже член? Вам это нужно только во время выполнения ctor, так почему вы держите его в живых? – MSalters

+0

Вы правы, поэтому вы имеете в виду, что я мог бы также написать: 'std :: mt19937 gen_ (std :: random_device())'? – beginneR

ответ

1

Вы можете просто удалить переменную члена std::random_device и использовать временный std::random_device при построении std::mt19937 gen_, как это:

#include <iostream> 
#include <random> 

class Sampler{  
private: 
    std::mt19937 gen_; 

public: 
    Sampler(); 
    double sample(); 
}; 

Sampler::Sampler() : gen_(std::random_device{}()) {} 

class Foo{ 
private: 
    Sampler s_; 

public: 
    Foo(Sampler); 
}; 

Foo::Foo(Sampler s) : s_(s) {} // Does work 

Попробуйте here.