From: micode on
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 &eng;
}
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! ]