我正在使用Boost multi_index容器根据2个整数键K1和K2存储对象。我可以轻松地检索满足“K1 == X”的所有元素的迭代器,例如,通过获取第一个索引并使用find()函数(对于K2和值Y),但我正在寻找一种方法获得满足K1 == X和K2 == Y的所有元素的迭代器。一个明显的解决方案是在满足K1 == X的所有元素上获得迭代器,然后使用谓词K2 == Y构建boost :: filter_iterator,但有没有办法(可能更有效)只能从Boost.MultiIndex?
由于
马修
答案 0 :(得分:7)
K1
和K2
同时使用boost::multi_index::composite_key。
这是一个小例子,也在ideone.com上:
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <iostream>
struct Stuff
{
Stuff (int iFirst, int iSecond)
: m_iFirst(iFirst),
m_iSecond(iSecond)
{
}
int m_iFirst;
int m_iSecond;
};
std::ostream& operator<<(std::ostream& rOut, Stuff const& rStuff)
{
return rOut << rStuff.m_iFirst << "/" << rStuff.m_iSecond << "\n";
}
struct FirstIdx{};
struct SecondIdx{};
struct BothIdx{};
typedef boost::multi_index_container<
Stuff,
boost::multi_index::indexed_by<
boost::multi_index::ordered_non_unique<boost::multi_index::tag<FirstIdx>, boost::multi_index::member<Stuff, int, &Stuff::m_iFirst> >,
boost::multi_index::ordered_non_unique<boost::multi_index::tag<SecondIdx>, boost::multi_index::member<Stuff, int, &Stuff::m_iSecond> >,
boost::multi_index::ordered_non_unique<boost::multi_index::tag<BothIdx>, boost::multi_index::composite_key<Stuff, boost::multi_index::member<Stuff, int, &Stuff::m_iFirst>,
boost::multi_index::member<Stuff, int, &Stuff::m_iSecond> > >
>
> TDicStuffs;
typedef TDicStuffs::index<FirstIdx>::type TFirstIdx;
typedef TDicStuffs::index<SecondIdx>::type TSecondIdx;
typedef TDicStuffs::index<BothIdx>::type TBothIdx;
int main(int argc, char *argv[])
{
TDicStuffs stuffs;
// fill some stuffs
stuffs.insert(Stuff(1, 1));
stuffs.insert(Stuff(1, 2));
stuffs.insert(Stuff(1, 3));
stuffs.insert(Stuff(2, 1));
stuffs.insert(Stuff(2, 2));
stuffs.insert(Stuff(2, 3));
stuffs.insert(Stuff(3, 1));
stuffs.insert(Stuff(3, 2));
stuffs.insert(Stuff(3, 3));
assert(stuffs.size() == 9);
// search for m_iFirst == 2
TFirstIdx::const_iterator itFirstLower;
TFirstIdx::const_iterator itFirstUpper;
boost::tie(itFirstLower, itFirstUpper) = stuffs.get<FirstIdx>().equal_range(2);
assert(std::distance(itFirstLower, itFirstUpper) == 3);
std::copy(itFirstLower, itFirstUpper, std::ostream_iterator<Stuff>(std::cout << "\n"));
// search for m_iSecond == 3
TSecondIdx::const_iterator itSecondLower;
TSecondIdx::const_iterator itSecondUpper;
boost::tie(itSecondLower, itSecondUpper) = stuffs.get<SecondIdx>().equal_range(3);
assert(std::distance(itSecondLower, itSecondUpper) == 3);
std::copy(itSecondLower, itSecondUpper, std::ostream_iterator<Stuff>(std::cout << "\n"));
// search for m_iFirst == 2 m_iSecond == 3
TBothIdx::const_iterator itBothLower;
TBothIdx::const_iterator itBothUpper;
boost::tie(itBothLower, itBothUpper) = stuffs.get<BothIdx>().equal_range(boost::make_tuple(2,3));
assert(std::distance(itBothLower, itBothUpper) == 1);
std::copy(itBothLower, itBothUpper, std::ostream_iterator<Stuff>(std::cout << "\n"));
return 0;
}