Boost:将指针存储到向量中的分布 [英] Boost: Store Pointers to Distributions in Vector
问题描述
Hi Stack Exchange Experts,
Hi Stack Exchange Experts,
我试图收集Boost在一个向量中提供的不同统计分布的指针。
如果分布从一个(虚拟)父类派生,我可以写成
I'm trying to collect pointers to different statistical distributions provided by Boost in one vector. If distributions would be derived from one (virtual) parent class I could write something 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 then iterate over the vector and apply functions etc. to the dereferenced pointers. But since this is not the case I don't really know how to store the pointers in one place?
所以我的问题是,如果有一个在一个变量/列表/向量中存储指向不同模板类的指针...(可以方便地处理,例如std :: vector)。
So my question is, if there is a way to store pointers to different template classes in one variable/list/vector... (that can be handled conveniently like std::vector for example).
例如Boost pdf密度函数可以应用于解除引用的指针,而不考虑具体类型(因此在某些情况下将它们存储在一个向量中是有意义的)。
Remark that for example the Boost pdf density function can be applied to the dereferenced pointers regardless of the specific type (so storing them in one vector makes sense in some cases).
// ////////////////////////////////////////////////// //////////////////////
//////////////////////////////////////////////////////////////////////////
我玩了不同的(好的)答案,最后决定坚持boost :: variant结合boost :: static_visitor。
下面是一个完整的应用程序,它做我在原来的问题中概述:
I played around with the different (nice) answers and finally decided to stick to boost::variant in conjunction with boost::static_visitor. Below is a full application that does what I outlined in my original question:
#include <boost/math/distributions.hpp>
#include <boost/variant.hpp>
#include <vector>
#include <iostream>
//template based visitor to invoke the cdf function on the distribution
class cdf_visitor_generic : public boost::static_visitor<double>
{
public:
//constructor to 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 a variant
Distribution v = t;
//example value for evaluation
double x = 1.96;
//evaluation at one point
double y = boost::apply_visitor( cdf_visitor_generic(x),v);
std::cout << y << std::endl;
//build a vector and apply to all elements of it:
std::vector<Distribution> vec_v;
vec_v.push_back(s);
vec_v.push_back(t);
for (std::vector<Distribution>::const_iterator iter = vec_v.begin(); iter != vec_v.end(); ++iter){
//apply cdf to dereferenced iterator
double test = boost::apply_visitor( cdf_visitor_generic(x), *iter);
std::cout << test << std::endl;
}
return 0;
}
我看到的唯一缺点是需要明确指定分发类型(在变体中),所以它可以是boost :: any添加更多的自由。
The only drawback I see is that the type of distribution needs to be explicitly specified (in the variant) so it could be that boost::any adds more freedom.
感谢您的大力帮助!
Hank
推荐答案
您可以使用变体
:
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);
我有几个答案显示如何使用这些元素多态(虽然多态是通过静态编译类型切换,而不是vtable dispatch)。我将很快添加一个或两个链接。
I have several answers that show how to use these elements "polymorphically" (though the polymorphism is by statically compile typeswitching, instead of vtable dispatch). I'll add a link or two soon.
- Generating an interface without virtual functions?
- Avoid RTTI when dealing with pairs of objects
- More involved: boost::mpl::fold for double parameter abstraction
一些链接的答案显示手动方法键入erasure
Some of the linked answers show the "manual" approach to type erasure
PS。我可能应该提到 boost :: any
,但我不喜欢它有几个原因。我不会为此目的推荐它。
PS. I should probably mention boost::any
too, but I dislike it for several reasons. I shan't recommend it for this purpose.
这篇关于Boost:将指针存储到向量中的分布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!