Boost:在Vector中存储指向分布的指针
Boost: Store Pointers to Distributions in Vector
大家好,
我试图在一个矢量中收集Boost提供的不同统计分布的指针。如果发行版是从一个(虚拟)父类派生的,我可以这样写
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);
,然后遍历vector,并对解引用指针应用函数等。但既然不是这样,我真的不知道如何将指针存储在一个地方?
所以我的问题是,如果有一种方法来存储指针到不同的模板类在一个变量/列表/向量…(这可以像std::vector一样方便地处理)。
请注意,例如Boost pdf密度函数可以应用于解引用指针,而不考虑具体类型(因此在某些情况下将它们存储在一个向量中是有意义的)。
//////////////////////////////////////////////////////////////////////////
我尝试了不同的(不错的)答案,最后决定将boost::variant与boost::static_visitor结合使用。下面是一个完整的应用程序,它完成了我在最初问题中概述的功能:
#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增加了更多的自由。
谢谢你的帮助!
汉克您可以使用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);
我有几个答案,展示了如何"多态"地使用这些元素(尽管多态是通过静态编译类型转换,而不是虚表调度)。我很快会添加一两个链接。
- 生成没有虚函数的接口?
- 在处理对象对时避免RTTI
- 更复杂:boost::mpl::fold用于双参数抽象
一些链接的答案显示了"手动"方法的类型擦除
<子> p。我可能也应该提到boost::any
,但我不喜欢它有几个原因。子>
不能在单个vector中存储指向不相关类型的指针。实现这一点的一种方法是创建一个void*:
的向量std::vector<void*>
但是我强烈建议你不要这样做,因为这不是c++的方式。
更好的解决方案是创建自定义类层次结构来存储不同类型的指针,例如:
class DistributionBase {
public:
virtual ~DistributionBase() {}
}
template<typename T>
class Distribution : public DistributionBase {
public:
typedef T DistributionType;
T* distribution;
Distribution(T* d) : distribution(d) {}
~Distribution() { delete distribution; }
}
template<typename T>
Distribution<T>* make_distribution(T* d) {
return new Distribution<T>(d);
}
然后你可以这样使用:
std::vector<DistributionBase*> distributions;
distributions.push_back(make_distribution(new boost::math::normal_distribution<double>(n)))
distributions.push_back(make_distribution(new boost::math::students_t_distribution<float>(n)))
问题是,您必须将分布类型存储在某个地方,以便您可以static_cast为正确的类型:
boost::math::normal_distribution<double>* d = static_cast< Distribution<boost::math::normal_distribution<double> > >(distributions[0])->distribution;
这只是一个片段,它应该向您展示要点,而不是一个完整的示例。
可以在公共基类周围包装指针。这里我将使用模板方法模式:
class Distribution {
public:
double pdf( double d) { doPdf( d)};
private:
virtual double doPdf( double d) {} = 0;
virtual ~Distribution() {}
};
class NormalDistribution : public Distribution {
private:
boost::math::normal_distribution<double> nd;
double doPdf( double d) { return pdf( nd, d);}
};
class StudentsTDistribution : public Distribution {
private:
boost::math::students_t_distribution<double> std;
double doPdf( double d) { return pdf( std, d);}
};
用法:
std::vector< boost::shared_ptr<Distribution> > v;
v.push_back( boost::make_shared<NormalDistribution>());
v.push_back( boost::make_shared<StudentsTDistribution>());
v[0]->pdf( 0.5); // draw from Gauss's distribution
v[1]->pdf( 0.5); // draw from fatter tails - t Student distribution
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- [C++]查找有关分布(函数)指针的错误
- Boost:在Vector中存储指向分布的指针