I need to use a random number generator very often, and instead of writing it everytime I need it I would like to make a class so that I can just link it into other programs. The current code I have is this:
#include <boost/random.hpp>
#include <iostream>
int main() {
boost::mt19937 rng(0);
boost::normal_distribution<float> dist_normal(0.0f,1.0f);
boost::variate_generator<boost::mt19937, boost::normal_distribution<float> > rand_normal(rng, dist_normal);
for(int i = 0 ; i < 10; ++i)
std::cout << rand_normal() << std::endl;
return 0;
}
But now I would like to separate interface and implementation like so:
#include <boost/random.hpp>
#include <iostream>
int main() {
//This goes in the header file as private members of class
boost::mt19937 rng;
boost::normal_distribution<float> dist_normal;
boost::variate_generator<boost::mt19937, boost::normal_distribution<float> > rand_normal;
//This is then in the constructor in the cpp file
rng = boost::mt19937(0);
dist_normal = boost::normal_distribution<float>(0.0f,1.0f);
rand_normal = boost::variate_generator<boost::mt19937, boost::normal_distribution<float> >(rng, dist_normal);
for(int i = 0 ; i < 10; ++i)
std::cout << rand_normal() << std::endl;
return 0;
}
But this does not compile, it gives me the following errors (oh the joy of deciphering boost errors):
test2.cpp: In function ‘int main()’:
test2.cpp:7:79: error: no matching function for call to ‘boost::random::variate_generator<boost::random::mersenne_twister_engine<unsigned int, 32ul, 624ul, 397ul, 31ul, 2567483615u, 11ul, 4294967295u, 7ul, 2636928640u, 15ul, 4022730752u, 18ul, 1812433253u>, boost::random::normal_distribution<float> >::variate_generator()’
test2.cpp:7:79: note: candidates are:
/usr/include/boost/random/variate_generator.hpp:69:5: note: boost::random::variate_generator<Engine, Distribution>::variate_generator(Engine, Distribution) [with Engine = boost::random::mersenne_twister_engine<unsigned int, 32ul, 624ul, 397ul, 31ul, 2567483615u, 11ul, 4294967295u, 7ul, 2636928640u, 15ul, 4022730752u, 18ul, 1812433253u>, Distribution = boost::random::normal_distribution<float>]
/usr/include/boost/random/variate_generator.hpp:69:5: note: candidate expects 2 arguments, 0 provided
/usr/include/boost/random/variate_generator.hpp:51:7: note: boost::random::variate_generator<boost::random::mersenne_twister_engine<unsigned int, 32ul, 624ul, 397ul, 31ul, 2567483615u, 11ul, 4294967295u, 7ul, 2636928640u, 15ul, 4022730752u, 18ul, 1812433253u>, boost::random::normal_distribution<float> >::variate_generator(const boost::random::variate_generator<boost::random::mersenne_twister_engine<unsigned int, 32ul, 624ul, 397ul, 31ul, 2567483615u, 11ul, 4294967295u, 7ul, 2636928640u, 15ul, 4022730752u, 18ul, 1812433253u>, boost::random::normal_distribution<float> >&)
/usr/include/boost/random/variate_generator.hpp:51:7: note: candidate expects 1 argument, 0 provided
And here I am stuck, from what I understand the second candidate is the copy constructor, but how should I read the first candidate and how should I change my code such that it works? Thanks in advance!
EDIT:
The working solution, thanks to muehlbau.
boost_rng.c:
#include "boost_rng.hpp"
BoostRNG::BoostRNG(uint _seed) : seed(_seed),
rng(boost::mt19937(_seed)),
dist_normal(boost::normal_distribution<float>(0.0f,1.0f)),
rand_normal(boost::variate_generator<boost::mt19937&, boost::normal_distribution<float> >(rng, dist_normal))
{}
float BoostRNG::normal() {
return rand_normal();
}
and boost_rng.hpp:
#include <boost/random.hpp>
class BoostRNG {
private:
uint seed;
boost::mt19937 rng;
boost::normal_distribution<float> dist_normal;
boost::variate_generator<boost::mt19937&, boost::normal_distribution<float> > rand_normal;
public:
BoostRNG(uint seed);
float normal();
};
Note that it works for references the the engine as well, letting me use the same engine for multiple generators ;)