Boost logo

Boost Users :

From: e r (erwann.rogard_at_[hidden])
Date: 2008-02-18 10:57:17


Hi All,

I have classes A and B as random distributions i.e. they have a member
function operator()(UniformRandomNumberGenerator&). I choose to make
UniformRandomNumberGenerator a class template instead of a member
function template (why? because in my non-simplified code
A::operator()(...) is virtual).

B has a member variable of type A that it uses for its implementation.
Passing UniformRandomNumberGerator& into the nested object's
A::operator()(...) causes a reference to reference problem that I solve
with call_traits. fine?

I want to wrap a boost::variate_generator around
UniformRandomNumberGenerator and B. The variate_generator does not pass
UniformRandomNumberGenerator& to A::operator()(...) but - i guess - a
decorated version of it. so I have to specify A<Decoration> instead of
A::<UniformRandomNumberGenerator> and likewise for B. I don't like this
manual fix (I have to look at the compiler errors to figure out
Decoration).

Maybe I could overload A and B's operator()(...) with something like
operator()(Decoration<UniformRandomRandomNumberGenerator>) but have not
succeeded.

Any better suggestion?

#include <boost/call_traits.hpp>
template<class UniformRandomNumberGenerator>
class A{
public:

typedef UniformRandomNumberGenerator urng_type;
typedef double input_type;
typedef double result_type;
typedef urng_type argument_type;
result_type operator()(argument_type u){return u();};
};
template<class UniformRandomNumberGenerator,template<class> class Impl>
class B{
public:
typedef UniformRandomNumberGenerator urng_type;
typedef Impl<urng_type> impl_type;
typedef double input_type;
typedef double result_type;
typedef typename impl_type::argument_type impl_argument_type;
typedef typename boost::call_traits<impl_argument_type>::reference
argument_type;
result_type operator()(argument_type u){return impl(u);};
private:
impl_type impl;
};

#include "A.hpp"
#include <boost/random.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/uniform_real.hpp>
typedef boost::mt19937 urng_type;
typedef boost::uniform_real<> rdu01_type;
typedef boost::variate_generator<urng_type&,rdu01_type> urng01_type;
typedef A<urng01_type> a0_type;
typedef B<urng01_type,A> b0_type;
typedef boost::variate_generator<urng01_type&,b0_type> rg0_type;
typedef
boost::uniform_01<boost::random::detail::pass_through_engine<urng01_type&>,double>
pass_through_engine_type; //manual fix, far from ideal
typedef A<pass_through_engine_type> a1_type;
typedef B<pass_through_engine_type,A> b1_type;
typedef boost::variate_generator<urng01_type&,b1_type> rg1_type;

int main(){
        urng_type urng;
        rdu01_type rdu01;
        urng01_type urng01(urng,rdu01);

        b0_type b0;
        std::cout << b0(urng01) << std::endl; //OK

// rg0_type rg0(urng01,b0);
// std::cout << rg0() << std::endl; // Error no match for call to
‘(B<boost::variate_generator<boost::random::mersenne_twister<unsigned
int, 32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u,
18, 3346425566u>, boost::uniform_real<double> >, A>)
(boost::uniform_01<boost::random::detail::pass_through_engine<urng01_type&>,
double>&)’ candidates are: double B<UniformRandomNumberGenerator,
Impl>::operator()(typename boost::call_traits<typename
Impl<UniformRandomNumberGenerator>::argument_type>::reference) [with
UniformRandomNumberGenerator =
boost::variate_generator<boost::random::mersenne_twister<unsigned int,
32, 624, 397, 31, 2567483615u, 11, 7, 2636928640u, 15, 4022730752u, 18,
3346425566u>, boost::uniform_real<double> >, Impl = A]

        b1_type b1;
        rg1_type rg1(urng01,b1);
        std::cout << rg1() << std::endl; //OK

        return 0;
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net