I have a multi_index_container
that looks basically like this:
struct MyStruct {
int a, b, c;
};
struct Tag1;
struct Tag2;
typedef multi_index_container<
MyStruct,
indexed_by<
hashed_non_unique<
tag<Tag1>,
composite_key<
MyStruct,
member<MyStruct, int, &MyStruct::a>,
member<MyStruct, int, &MyStruct::b>
>
>,
hashed_non_unique<
tag<Tag2>,
composite_key<
MyStruct,
member<MyStruct, int, &MyStruct::a>,
member<MyStruct, int, &MyStruct::b>,
member<MyStruct, int, &MyStruct::c>
>
>
>
> MyContainer;
I instantiate such a container and use its indices like so:
MyContainer c;
MyContainer::index<Tag1>::type& index1 = c.get<Tag1>;
MyContainer::index<Tag2>::type& index2 = c.get<Tag2>;
Now, at runtime, I want to do an equal_range
on one of the two indices. Which index is actually used, is dependent on the current configuration. What I'm trying to accomplish is something like this:
// Search in container
SomeType range;
if (useIndex1)
range = index1.equal_range(...);
else
range = index2.equal_range(...);
// Loop through range
for (auto i = range.first; i != range.second; ++i)
...
I don't know how to do this. As it turns out, the return type of index1.equal_range
is a pair of iterators that are different from those returned by index2.equal_range
. Is there a common base type to the two? Looking at my example, what would SomeType
have to look like? I don't want to repeat the for
loop in my code for every index that may possibly be used.
Instead of trying to do type erasure with range, put your loop logic into a lambda and apply it using std::for_each:
#include <boost\multi_index_container.hpp>
#include <boost\multi_index\composite_key.hpp>
#include <boost\multi_index\member.hpp>
#include <boost\multi_index\hashed_index.hpp>
using namespace boost::multi_index;
struct MyStruct {
int a, b, c;
};
struct Tag1;
struct Tag2;
typedef multi_index_container
<
MyStruct
, indexed_by
<
hashed_non_unique
<
tag<Tag1>
, composite_key
<
MyStruct
, member<MyStruct, int, &MyStruct::a>
, member<MyStruct, int, &MyStruct::b>
>
>
, hashed_non_unique
<
tag<Tag2>
, composite_key
<
MyStruct
, member<MyStruct, int, &MyStruct::a>
, member<MyStruct, int, &MyStruct::b>
, member<MyStruct, int, &MyStruct::c>
>
>
>
> MyContainer;
int main()
{
MyContainer c;
MyContainer::index<Tag1>::type& index1 = c.get<Tag1>();
MyContainer::index<Tag2>::type& index2 = c.get<Tag2>();
//! Add some values
for (int i = 0; i < 10; ++i)
{
MyStruct s = { i, i * 2, i * 3 };
c.insert(s);
}
auto loop = [](const MyStruct& s){ std::cout << "{ " << s.a << ", " << s.b << ", " << s.c << " }" << std::endl; };
// Search in container
bool useIndex1 = true;
if (useIndex1)
{
auto range = std::make_pair(index1.begin(), index1.end());
std::for_each(range.first, range.second, loop);
}
else
{
auto range = std::make_pair(index1.begin(), index1.end());
std::for_each(range.first, range.second, loop);
}
// Loop through range
//for (auto i = range.first; i != range.second; ++i)
return 0;
}