Boost Multi_Index问题 [英] Boost Multi_Index Question
问题描述
对不起,我不能在标题中更具体。
假设我有一个Foo类
class Foo {
public:
Foo(){m_bitset.reset(); }
void set_i(int i){
m_bitset.set(1);
m_i = i;
}
void set_j(int j){
m_bitset.set(2);
m_j = j;
}
bool i_set(){return m_bitset(1); }
bool j_set(){return m_bitset(2); }
void clear_i(){m_bitset.reset(1); }
void clear_j(){m_bitset.reset(2); }
int get_i(){
assert(i_set());
return m_i;
}
int get_j(){
assert(j_set());
return m_j;
}
private:
int m_i,m_j;
bitset< 2> m_bitset;
};
现在我想把Foo放到一个multi_index。
typedef multi_index_container<
Foo,
indexed_by<
ordered_non_unique< BOOST_MULTI_INDEX_CONST_MEM_FUN(Foo,int,get_i)
>,
ordered_non_unique< BOOST_MULTI_INDEX_CONST_MEM_FUN(Foo,int,get_j)
>
>
> Foo_set;
我想知道的是一个方法让我的multi_index排序Foo有效值或i或j(或在一个composite_key的情况下和通过其余的
所以我不想让下面的代码爆炸,我只是想返回foos有有效的值为i 。
for(Foo_set :: nth_index< 1> :: type :: iterator it = foos.get& .begin(); it!= foos.get< 1>()。end(); ++ it)
pre>
cout
解决方案
中有
和assert()
get_i()get_j()
函数将导致硬程序停止,当multi_index询问i
或j
。
听起来你想要空对象模式行为Ie
m_i
和m_j
是使用特殊值表示它们未设置的数据类型(如果它们是指针, code> NULL 指针将用于此目的)。然后,您的多索引可以对这些值建立索引,将所有null
值合并。
,您可以使用 boost :: range 过滤掉空值:
//空测试的原语
struct is_not_null {
bool operator()(const Foo& f){return f.get_i()!= NULL&& f.get_j()!= NULL; }
};
Foo_set :: nth_index< 1> :: type& idx = foos.get< 1>();
BOOST_FOREACH(const Foo& f,idx | filtered(is_not_null())){
; //使用非空Foo的
执行操作}
如果你不想污染变量的值空间(即没有有意义的空值可以存储)也可以考虑将您的
m_i
和m_j
成员转换为 boost :: optional 。有了更多的函数包装,你可以创建一个< bool,int>
的复合索引,这将允许你访问set或unsetFoo
。您可以进一步组合索引,将i
和j
与看起来像< bool,bool,int,int>
。Sorry I can't be more specific in the title.
Let's say I have a class Foo
class Foo { public: Foo() { m_bitset.reset(); } void set_i(int i) { m_bitset.set(1); m_i = i; } void set_j(int j) { m_bitset.set(2); m_j = j; } bool i_set() { return m_bitset(1); } bool j_set() { return m_bitset(2); } void clear_i() { m_bitset.reset(1); } void clear_j() { m_bitset.reset(2); } int get_i() { assert(i_set()); return m_i; } int get_j() { assert(j_set()); return m_j; } private: int m_i, m_j; bitset<2> m_bitset; };
And now I want to put Foo's into a multi_index.
typedef multi_index_container < Foo, indexed_by< ordered_non_unique<BOOST_MULTI_INDEX_CONST_MEM_FUN( Foo, int, get_i) >, ordered_non_unique<BOOST_MULTI_INDEX_CONST_MEM_FUN( Foo, int, get_j) > > > Foo_set;
What I'm trying to figure out is a way to have my multi_index sort the Foo's that have valid values of i or j (or both in the case of a composite_key and pass over the rest. So I don't want the code below to blow up, I just want to only return foos that have valid values for i.
for (Foo_set::nth_index<1>::type::iterator it = foos.get<1>().begin(); it != foos.get<1>().end(); ++it) cout << *it;
解决方案Having
assert()
in yourget_i()
andget_j()
functions will cause a hard program stop when multi_index asks for thei
orj
values for indexing.It sounds like you want Null Object Pattern behaviour. I.e.
m_i
andm_j
are data-types that take special values to indicate they are not set (if they were pointers, theNULL
pointer would serve this purpose). Then your multi-index could index on those values, lumping all thenull
values together.When accessing the data, you can use boost::range to filter out the null values:
// Predicate for null testing struct is_not_null { bool operator()(const Foo& f) { return f.get_i() != NULL && f.get_j() != NULL; } }; Foo_set::nth_index<1>::type& idx = foos.get<1>(); BOOST_FOREACH(const Foo& f, idx | filtered(is_not_null())) { ;// do something with the non-null Foo's }
If you don't want to pollute the value-space of your variables (i.e. there is no meaningful null value that can be stored), you could also look into converting your
m_i
andm_j
members into boost::optional's. With a bit more functor wrapping, you could create a composite index of<bool, int>
, which would allow you to access set or unsetFoo
's separately. You can further compose the index to combinei
andj
with a composite index that looks like<bool, bool, int, int>
.这篇关于Boost Multi_Index问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!