Hi Kevin, others, Thank you for your responses, sorry for the long delay. I have decided to try to do without the whole singleton (although I don't really see what the point is of avoiding a singleton if we still have a global pointer, its almost the same thing) as an exercise and try out Kevin's implementation. I made some small changes to the code (code at bottom fo post) to make sure that the generator is constructed if it wasn't yet (and seeded in the process) so i don't have to do that by hand in my code. That exactly fits what i need, and as it is seeded automatically, i cannot forget to do so. I would never want to change my seed, nor be able to set it to a specific value manually. On Wed, Aug 5, 2009 at 12:10 AM, Kevin Martin<kev82@khn.org.uk> wrote:
On 4 Aug 2009, at 06:39, Diederick C. Niehorster wrote:
I have looked it up, thank you for the suggestion. I, however do not see the advantage of wrapping the generator.
Well you are wrapping up the variate_generator yourself with your specializations of the CRandom template. My suggestion is that instead of your CRandom class, you just return the variate_generator inside a boost function.
Hmm, i have tried so, but the syntax to actually extract the random numbers becomes very complicated now (I think i am missing a point here, i am new to boost.function). With my class, i could simply create an instance of a variate generator and then get a random number using the () operator. See example: CRandom<boost::uniform_int<int>> Cr(1,100); int test = Cr(); which with a typedef "typedef CRandom<b::uniform_int<int>> CRandomI;" i can easily shorten to: CRandomI Cr(1,100); int test = Cr(); I have only managed to find two ways to get my random number using the boost.function approach, both of which need considerably more typeing by the user. It makes me want to wrap the boost.function in a class... (Method one is stupid of course, it would generate a new distribution every time i request a number.) What step am I still missing here? Thanks and best regards, Diederick ---- // includes #include <boost/random.hpp> #include <time.h> #include <iostream> #include <boost/shared_ptr.hpp> #include <boost/function.hpp> // could use a macro to set the generator used in the code, for easy change // kevin martin: static boost::shared_ptr<boost::mt19937> generator_; void grng_setGenerator(boost::shared_ptr<boost::mt19937> ptr) { if(!ptr) throw std::runtime_error("Tried to set generator to NULL pointer"); if(generator_) throw std::runtime_error("Tried to set generator more than once"); generator_ = ptr; } boost::mt19937 &grng_generator() { if(generator_) return *generator_; // if doesn't exist, set grng_setGenerator(boost::shared_ptr<boost::mt19937>(new boost::mt19937(unsigned int(time(NULL))))); if(generator_) return *generator_; // if still doesn't exist, error throw std::runtime_error("Requested RNG, but there isn't one"); } template<class Distribution_> boost::function<typename Distribution_::result_type ()> grng_randomVariable(const Distribution_ &d) { boost::variate_generator<boost::mt19937&, Distribution_> rv(grng_generator(), d); return boost::function<typename Distribution_::result_type ()>(rv); } //main int main(int argc, char* argv[]) { // 1 int a = grng_randomVariable(boost::uniform_int<int>(1,100))(); std::cout << a << std::endl; // 2 boost::function<int ()> Ci(grng_randomVariable(boost::uniform_int<int>(1,100))); std::cout << Ci() << std::endl; return 1; }