我需要创建一个映射,从整数到元组集,单个集合中的元组具有相同的大小。问题是元组的大小及其参数类型可以在运行时确定,而不是在编译时确定。我想象的是:
std::map<int, std::set<boost::tuple> >
但并不完全确定如何正确地执行此操作,专门使用指针。
这样做的目的是创建临时关系(表),每个关系都有一个唯一的标识符(key),也许你有另一种方法。
答案 0 :(得分:4)
boost::tuple
的目的是混合任意类型。如果,如你所说,
我只插入整数
然后你应该使用map< int, set< vector< int > > >
。 (如果我是你,我会抛出一些typedef
。)
要回答原始问题,boost::tuple
在运行时不允许任意类型。 boost::any
。但是,any
不支持比较,因此如果您想在set
中使用它,还有一些工作要做。
typedef vector< boost::any > tuple;
struct compare_tuple { bool operator()( tuple const &l, tuple const &r ) const {
assert ( l.size() == r.size() );
for ( tuple::iterator lit = l.begin(), rit = r.begin();
lit != l.end(); ++ lit, ++ rit ) {
assert ( lit->type() == rit->type() );
if ( lit->type() == typeid( foo ) ) { // find the type and perform "<"
return boost::any_cast<foo>(*lit) < boost::any_cast<foo>(*rit);
} else if ( lit->type() == typeid( bar ) ) {
return boost::any_cast<bar>(*lit) < boost::any_cast<bar>(*rit);
} /* etc; you will need to enumerate all the types you can insert */
}
} };
typedef std::map< int, std::set< tuple, compare_tuple > > main_map;
答案 1 :(得分:2)
作为一个现代的旁注(如前所述,大约在2010年),今天的Variadic模板对此非常有用:
is_page()
答案 2 :(得分:0)
如果您有一些共同的基类,则只能将这些不同的集存储在同一个集合中。您可以编写一个抽象接口,然后为每种表/元组实现它。问题是,通常这样的界面往往非常混乱,如果你有许多类型的表/元组,你可能会有类爆炸。 Boost.Any对于这样的接口可能很有用(因为你必须动态处理不同的数据类型)。
答案 3 :(得分:0)
如果参数类型有共同点,请将其捕获到抽象基类中,并使元组包含指向此基类的指针:
class MyParamBase {
public:
virtual int getFoo() = 0;
virtual void setFoo(int) = 0;
};
std::map<int, std::set<MyParamBase*> > container;
(为简洁省略了boost :: tuple。不确定为什么需要一组元组。)
然后,您可以从MyParamBase派生具体参数类型,并创建并将它们插入到地图中:
class SomeParam: MyParamBase {
public:
virtual int getFoo() { ... }
virtual void setFoo(int a) { ... }
};
std::set<MyParamBase*> some_set;
some_set.insert(new SomeParam());
container[123] = some_set;
如果参数类型没有任何共同点 - 请勿将它们放在同一个地图中。很可能他们不属于一起。