Prev: TypeTraits for Parameters
Next: Can there be parallel initialization of global variables in C++0x?
From: micode on 27 May 2010 04:08 As this example describes, the results with a template type argument can be very different from the results with a pointer or reference template type. The current crop of compilers "do the right thing" with pointer or reference template type arguments. Can pointer or reference type arguments be rewritten to work with slightly older compilers? Summarizing Becker2007 sections 13.2 and 13.8: Applications can share a TR1 random number engine's state. The class variate_generator class template consolidates a generator and a distribution into a single object, and the template type argument names a generator type, or a pointer or reference to a generator type. The generator type argument starts the engines and distributions with the same state, so they generate the same sequence of values. The pointer or reference to a generator type argument shares the engine with the distributions, so that each call to a distribution changes the shared state of the engine, and subsequent calls use its new state. The variate_generate class template also adapts the engine to the exact type the distribution expects. A template wrapper simplifies this, as shown in the code below. A singleton (Meyers singleton) ensures engine reuse. Everything works fine under GCC 4.5.0. All three forms (the generator type, pointer and reference to a generator type) compile under the default language dialect (gnu++98) and c++0x. The c++98 dialect supports the generator type and pointer to a generator type. While I wouldn't expect reference reference types to compile under GCC 4.2.1, it is somewhat surprising that the pointer type cannot be instantiated. Only the rgen class template compiles. There is a workaround to get not-repeating sequences (call eng.seed(value) from rgen::ref) but that has other issues. Is there a way to modify the rgenP for earlier compilers, while preserving the shared-generator / unique-sequence semantic? /* *********************************************************************** * Conformance example of template type, pointer type and reference type * * ********************************************************************* */ #include <iostream> #include <limits> #include <vector> #include <tr1/random> using std::tr1::normal_distribution;using std::tr1::mt19937;using std::tr1::variate_generator; using std::numeric_limits;using std::cout; using std::endl; template <class ENGTYP=mt19937> class rgenP { static ENGTYP *ref() { static ENGTYP eng(ENGTYP(time(NULL)+rand())); return ŋ } public: template< template <typename> class Distribution_ = normal_distribution, typename S = double> //POINTER to its engine class rvar : public variate_generator<ENGTYP*, Distribution_<S> > { public: rvar(S p0=0, S p1=1) : variate_generator<ENGTYP*, Distribution_<S> >(ref(),Distribution_<S>(p0,p1)) {} }; }; template <class ENGTYP=mt19937> class rgenR { static ENGTYP &ref() { static ENGTYP eng(ENGTYP(time(NULL)+rand())); return eng; } public: template< template <typename> class Distribution_ = normal_distribution, typename S = double> //REFERENCE to its engine class rvar : public variate_generator<ENGTYP&, Distribution_<S> > { public: rvar(S p0=0, S p1=1) : variate_generator<ENGTYP&, Distribution_<S> >(ref(),Distribution_<S>(p0,p1)) {} }; }; template <class ENGTYP=mt19937> class rgen { static ENGTYP &ref() { static ENGTYP eng(ENGTYP(time(NULL)+rand())); return eng; } public: //COPY of engine template< template <typename> class Distribution_ = normal_distribution, typename S = double> class rvar : public variate_generator<ENGTYP, Distribution_<S> > { public: rvar(S p0=0, S p1=1) : variate_generator<ENGTYP, Distribution_<S> >(ref(),Distribution_<S>(p0,p1)) {} }; }; int main() { rgen<mt19937>::rvar<> dA, dA2; rgenR<mt19937>::rvar<> dB, dB2; rgenP<mt19937>::rvar<> dC, dC2; cout << "[same] cpy: " << dA() << " " << dA2() << endl; cout << "[diff] ref: " << dB() << " " << dB2() << endl; cout << "[diff] ptr: " << dC() << " " << dC2() << endl; return 0; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: TypeTraits for Parameters Next: Can there be parallel initialization of global variables in C++0x? |