模板异构类型的集合
Collection of template-heterogeneous types
我有一堆boost::property_map
s定义了图中遍历边的代价。我正在执行一个算法与这些地图的不同加权组合,目前通过手动做totalcost = weight1*weight1_factor + weight2*weight2_factor + ...
。然而,属性映射的数量正在增加,像这样总结它们变得很麻烦。
因此,我设想创建一个聚合类,它包含某种类型的所有映射的集合。然而,它们的模板是不同的,如boost::property_map<Graph, PropertyTag>
,其中PropertyTag
在地图中是不同的。既然它们都支持operator[](edge_escriptor)
,那么我是否可以使用一些技巧,或者我注定要使用boost::any
?
我建议你创建一个包含属性映射和因子的boost::元组
考虑到在您的上下文中,对于每个i都有(propertymap_i, weight_i),创建一个聚合类,该类使用该元组(作为聚合类的模板参数)在被请求时计算所需的值。
您可以使用operator[]或属性映射提供的get()函数。
如果需要的话,我可能会说得更清楚,但这得等一会儿了。
编辑:这是接近你需要的吗?
#include <boost/graph/adjacency_list.hpp>
#include <iostream>
#include <boost/shared_ptr.hpp>
namespace property_aggregator
{
template<typename Tuple, typename T>
struct helper
{
double operator()(Tuple const& tuple, T t)
{
return boost::get<0>(tuple)*get(boost::get<1>(tuple), t) +
helper<typename Tuple::tail_type::tail_type, T>()(tuple.get_tail().get_tail(), t);
}
};
template<typename T>
struct helper<boost::tuples::null_type, T>
{
double operator()(boost::tuples::null_type const& tuple, T t)
{
return 0.;
}
};
template<typename T>
class BasePropertyAggregator
{
public:
virtual double compute( T t ) = 0;
};
template <typename PropertyTuple, typename T>
class PropertyAggregator : public BasePropertyAggregator<T>
{
public:
PropertyAggregator(PropertyTuple const& tuple) : m_tuple(tuple){}
virtual ~PropertyAggregator(){}
double compute( T t )
{
return property_aggregator::helper<PropertyTuple, T>()(m_tuple, t);
}
private:
PropertyTuple m_tuple;
};
}
template<typename T>
class PropertyAggregator
{
public:
template<typename Tuple>
PropertyAggregator(Tuple const& tuple) : m_computer(new property_aggregator::PropertyAggregator<Tuple, T>(tuple))
{}
double operator()(T t)
{
return m_computer->compute(t);
}
private:
boost::shared_ptr<property_aggregator::BasePropertyAggregator<T> > m_computer;
};
// Defaut type of a graph
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS,
boost::property<boost::vertex_index_t, unsigned int>,
boost::property<boost::edge_weight_t, double,
boost::property<boost::edge_color_t, double> > > Graph;
int main()
{
typedef boost::property_map<Graph, boost::edge_weight_t>::type PM1;
typedef boost::property_map<Graph, boost::edge_color_t>::type PM2;
typedef boost::graph_traits<Graph>::edge_descriptor EdgeType;
Graph g;
PM1 pm1 = get(boost::edge_weight, g);
PM2 pm2 = get(boost::edge_color, g);
add_vertex(g);
add_vertex(g);
EdgeType edge1 = boost::add_edge(0, 1, g).first;
put(pm1, edge1, 1.);
put(pm2, edge1, 2.);
typedef PropertyAggregator<EdgeType> ComboType;
ComboType combo1(boost::make_tuple(1., pm1));
ComboType combo2(boost::make_tuple(1., pm2));
ComboType combo3(boost::make_tuple(1., pm1, 2., pm2));
std::cout << "-- " << combo1(edge1) << std::endl;
std::cout << "-- " << combo2(edge1) << std::endl;
std::cout << "-- " << combo3(edge1) << std::endl;
return 0;
}
创建一个抽象的BasePropertyMap类,该类具有用于公共功能的纯虚拟方法。创建从这个基类派生的模板类,并在boost_property_map专门化上进行模板化。在派生模板类型中,通过指针或值保存property_map,并用模板化属性映射的代码覆盖基类虚函数。
然后可以动态地创建派生类型对象,并通过基类指针将它们保存在集合中。
假设你想求和所有属性映射的权重,你可以写一个模板函数来计算单个属性映射的权重,它会像这样:
template<typename Graph, typename PropertyTag>
double calc_weight(const boost::property_map<Graph, PropertyTag>& propMap) {
// your body here
}
class BasePropertyMap {
virtual double weight() = 0;
}
template<typename Graph, typename PropertyTag>
class DerivedPropertyMap: public BasePropertyMap {
boost::property_map<Graph, PropertyTag> my_map;
double weight() {
return calc_weight(my_map);
}
}
std::vector<BasePropertyMap*> collection;
[...]
// iterate over collection
totalcost=0;
for(auto it=collection.begin(), endit = collection.end(); it!=endit; ++it) {
totalcost += (*it)->weight();
}
- C++中的集合(异构类型的数组)
- 整数到模板类型集合(C++)
- 将基元类型插入到集合中
- 使用模板C++任何集合类型的包装器
- 如何从C 中的集合中检索多个继承类型
- 我可以按类类型访问哪些类型的集合,并在必要时返回未找到
- 创建一个抽象类类型的集合,shared_ptr的抽象类向量
- C++集合方法:函数'setCost'不可行:'this'参数的类型'const value_type'
- C - 如何将自己类型的值插入集合中
- Boost:当缺少类型时,如何通过基指针序列化/反序列化泛型类型集合
- 集合类型的可变长度参数列表
- 有没有可能拥有C++模板函数,它接受任何类型T的集合
- 管理模板化派生类型的向量集合
- 以前这样做过吗?(Monad视图包装用于链操作的c++集合/类型)
- 循环访问类中的不同集合类型
- 多个类型的对象的集合
- 同时持有不同类型的集合
- 具有按类型键控的变量类型的C++集合
- 集合类型:如何存储bool、string类型的列表
- 对于每个模板类型,都有一个集合类型的实参