c++ - Boost: Store Pointers to Distributions in Vector -
hi stack exchange experts,
i'm trying collect pointers different statistical distributions provided boost in 1 vector. if distributions derived 1 (virtual) parent class write like
std::vector<parent> v; boost::math::normal_distribution<double> n; boost::math::students_t_distribution<float> t(4); boost::math::normal_distribution<double> *p1 = new boost::math::normal_distribution<double>(n); boost::math::students_t_distribution<float> *p2 = new boost::math::students_t_distribution<float>(t); v.push_back(p1); v.push_back(p2);
and iterate on vector , apply functions etc. dereferenced pointers. since not case don't know how store pointers in 1 place?
so question is, if there way store pointers different template classes in 1 variable/list/vector... (that can handled conveniently std::vector example).
remark example boost pdf density function can applied dereferenced pointers regardless of specific type (so storing them in 1 vector makes sense in cases).
//////////////////////////////////////////////////////////////////////////
i played around different (nice) answers , decided stick boost::variant in conjunction boost::static_visitor. below full application outlined in original question:
#include <boost/math/distributions.hpp> #include <boost/variant.hpp> #include <vector> #include <iostream> //template based visitor invoke cdf function on distribution class cdf_visitor_generic : public boost::static_visitor<double> { public: //constructor handle input arguments cdf_visitor_generic(const double &x) : _x(x) {} template <typename t> double operator()(t &operand) const { return(boost::math::cdf(operand,_x)); } private: double _x; }; //shorten typing typedef boost::variant< boost::math::normal_distribution<double>, boost::math::students_t_distribution<double> > distribution; int main (int, char*[]) { //example distributions boost::math::normal_distribution<double> s; boost::math::students_t_distribution<double> t(1); //build variant distribution v = t; //example value evaluation double x = 1.96; //evaluation @ 1 point double y = boost::apply_visitor( cdf_visitor_generic(x),v); std::cout << y << std::endl; //build vector , apply elements of it: std::vector<distribution> vec_v; vec_v.push_back(s); vec_v.push_back(t); (std::vector<distribution>::const_iterator iter = vec_v.begin(); iter != vec_v.end(); ++iter){ //apply cdf dereferenced iterator double test = boost::apply_visitor( cdf_visitor_generic(x), *iter); std::cout << test << std::endl; } return 0; }
the drawback see type of distribution needs explicitly specified (in variant) boost::any adds more freedom.
thank great help!
hank
you can use variant
:
std::vector<boost::variant< boost::math::normal_distribution<double>, boost::math::students_t_distribution<float> > > v; boost::math::normal_distribution<double> n; boost::math::students_t_distribution<float> t(4); v.push_back(n); v.push_back(t);
i have several answers show how use these elements "polymorphically" (though polymorphism statically compile typeswitching, instead of vtable dispatch). i'll add link or 2 soon.
- generating interface without virtual functions?
- avoid rtti when dealing pairs of objects
- more involved: boost::mpl::fold double parameter abstraction
some of linked answers show "manual" approach type erasure
ps. should mention boost::any
too, dislike several reasons. shan't recommend purpose.
Comments
Post a Comment