random variate_generator, call_traits...
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; }
participants (1)
-
e r