Slava
Slava

Reputation: 44258

How to create boost multi_index key to a member of member?

Let's say I have following:

struct foo {
   int i;
};

struct bar {
    foo f;
};

is there a way to create a key to f.i (except wrapping to function) for container, holding struct bar?

Straightforward way does not seem to work:

namespace mpi = boost::multi_index;
typedef mpi::multi_index_container<bar,
     mpi::indexed_by< mpi::hashed_unique<bar,
         mpi::member< bar, int, &bar::fo.i>>
> > Foobar;

Upvotes: 2

Views: 605

Answers (2)

Mark B
Mark B

Reputation: 96241

multi-index's member index helper is only designed to access direct members of the value class, and can't be composed in a nested way.

Instead use the intended mechanism and write your own key extractor. It will make code maintenance much easier than trying to utilize the basic built in functionality for something it was never supposed to accomplish.

struct foo_i_from_bar
{
    typedef int result_type;
    result_type operator()(const bar& b) const { return b.f.i; }
};

typedef boost::multi_index::multi_index_container<bar,
     boost::multi_index::indexed_by< boost::multi_index::hashed_unique<foo_i_from_bar>
         > > Foobar;

Upvotes: 3

Rabbid76
Rabbid76

Reputation: 210948

It's ugly but it works.

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>

struct foo {
    int i;
};

struct bar {
    typedef int result_type;
    foo f;
};

namespace mpi = boost::multi_index;

typedef mpi::member< bar, int, (int bar::*)( offsetof(bar,f.i) )> bar_member;
                                         //  ^^^^^^^^ bar::f.i      

typedef mpi::multi_index_container< bar, mpi::indexed_by< mpi::hashed_unique<bar, bar_member > > > Foobar;

Foobar foobar;

... this works too ...

typedef mpi::member< bar, int, (int bar::*)( (size_t)&(((bar*)0)->f.i) )> bar_member;

Upvotes: 1

Related Questions