Using C ++ 0x TR1 in a class, for low overhead

I use VC 2010 and try to keep the overhead and duplicate codes of some functions low by putting random definitions in the constructor of each instance of the class, and then calling from there if necessary. I have now simplified:

#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, this does not work, and I get this error:

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

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

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

I understand that they must be initialized before the constructor is opened, otherwise these are errors due to the lack of a default constructor, but I do not understand why this fails. My C ++ fu is pretty rusty.

Each example that I saw shows that the distributor and generator are initialized globally or locally in a function that calls it, which seems silly to me, because I have several member functions that will use r_norm, called in a closed loop. It is bad copes with the smell. Doesn't anyone know what I'm missing?

+4
source share
3 answers

bind() used in C ++ 0x instead of variate_generator<> :

 #include <functional> // bind #include <iostream> #include <vector> #include <random> namespace { std::random_device generate_seed; std::mt19937 eng(generate_seed()); class Cycles { int line; std::normal_distribution<> rand_norm; std::function<double()> r_norm; public: Cycles(): line(0), rand_norm(0.85, 0.05), r_norm(std::bind(rand_norm, eng)) { // print distribution std::vector<size_t> freq(200); for (int i = 0; i < 900; ++i) ++freq.at(std::round(r_norm()*100)); size_t line = 0, max_line = freq.size()-1; for ( ; not freq[line] and line <= max_line; ++line); for ( ; not freq[max_line] and max_line >= line; --max_line); for ( ; line <= max_line; ++line) { std::cout << line << '\t'; for (size_t j = 0; j < freq[line]; ++j) std::cout << '*'; std::cout << std::endl; } } }; } int main() { Cycles c; } 

The plot is inspired by C ++ 0xFAQ .

Output

 72 ** 73 *** 74 ****** 75 ******** 76 ***************** 77 ******************** 78 ******************************* 79 ************************************************ 80 ************************************************* 81 ********************************************************** 82 ************************************************************ 83 *********************************************************** 84 ************************************************************************ 85 ******************************************************************************** 86 ********************************************************************* 87 ************************************************************ 88 **************************************************** 89 ************************************* 90 ********************************** 91 ************************************** 92 ************************* 93 ****************** 94 ******************** 95 ************ 96 **** 97 ********** 98 *** 99 ** 100 ** 101 * 
+6
source

don't have MSVC on 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 & )

By the way, std::random_device is probably a better source of randomness than GetTickCount() , although I don’t know how it is implemented in MSVC.

+3
source
 mt19937 eng(GetTickCount()); 

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

-1
source

All Articles