views:

106

answers:

2

Hello, I'm using VC 2010 and trying to keep the overhead and duplicated code of certain functions low, by placing the random definitions in the constructor of each class instance, then calling as necessary from there. What I have now, simplified, is:

#include <random>
#include <Windows.h>
mt19937 eng(GetTickCount());

class Cycles {
    int line;
    normal_distribution<> rand_norm;
    variate_generator<mt19937&,normal_distribution<>> r_norm;
public:
    Cycles() 
    : rand_norm(0.85,0.05),
      r_norm(eng,rand_norm) { 
        line=0; 
    }
}

Unfortunately that doesn't work, and I end up with this error:

\vc\include\random(513): error C2248: 'std::tr1::_Ewrap<_Engine,_Tgt_type>::operator =' : cannot access private member declared in class 'std::tr1::_Ewrap<_Engine,_Tgt_type>'

\vc\include\random(446) : see declaration of 'std::tr1::_Ewrap<_Engine,_Tgt_type>::operator ='

This diagnostic occurred in the compiler generated function 'std::tr1::variate_generator<_Engine,_Distrib> &std::tr1::variate_generator<_Engine,_Distrib>::operator =(const std::tr1::variate_generator<_Engine,_Distrib> &)'

I understand that these should be initialized prior to the opening of the constructor, or else it errors because of the lack of a default constructor, but I don't understand why this fails. My C++ fu is quite rusty.

Every example I've seen shows the distributor and generator being initialized globally or locally in the function that calls it, which seems silly to me, as I have several member functions that will be using r_norm that are called in a tight loop. It fails the smell test badly. Doesn't anyone know what I'm missing?

A: 
mt19937 eng(GetTickCount());

You cannot initialize a global variable with a non-static expression.

Alexander Rafferty
Where did you hear that?
PigBen
This is true in C, but not C++.
Roger Pate
+3  A: 

don't have MSVC at hand, but with gcc, this will compile if you replace

variate_generator<mt19937&,normal_distribution<>> r_norm;

with

variate_generator<mt19937, normal_distribution<> > r_norm;

(note the lack of &)

Incidentally, std::random_device is probably a better source of randomness than GetTickCount(), although I don't know how it's implemented in MSVC.

Cubbi