Search code examples
c++randomcopy-constructormersenne-twister

Proper copy of RNG in C++


I have a class containing a RNG:

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

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

The class is initialized as follows:

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

My problem is that I want to use this class (the member function sample()) inside another class but I cannot copy the class because std::random_device cannot be copied (the copy constructor is deleted since otherwise the same random numbers would be generated).

class Foo{
private:
    Sampler s_;

public:
    Foo(Sampler);

};

And then:

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

While this makes total sense I wonder how one would implement this in order to make it work. I've read that one opportunity would be to construct a proper copy constructor such that every time a copy is made, it gets seeded with a new seed but I don't know how to do this.


Solution

  • You could just remove the std::random_device member variable and use temporary std::random_device when constructing std::mt19937 gen_, like this:

    #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
    

    Try it here.