0

I have a multi_index_container with an index that is a composite_key. But I can not find a way to erase an element by its key. Please see below:

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

using namespace boost::multi_index;

struct Point
{
    int x, y;
};

void func()
{
  multi_index_container<Point,indexed_by<
    hashed_unique<
      composite_key<Point,
                    member<Point,int,&Point::x>,
                    member<Point,int,&Point::y> >
      > > > points;

  points.find( boost::make_tuple( 3, 3 ) );    // <- works
  points.erase( boost::make_tuple( 3, 3 ) );   // <- failes to compile
}

erase(key) works for indices that are not composite. But I am unable to find the correct syntax for composite keys.

Dev Null
  • 4,731
  • 1
  • 30
  • 46

2 Answers2

3

erasedoesn't have the type of overloads that allow for interoperation with tuples (technically, this relates to the concept of compatible extensions.) But you can have the same effect with a little more code:

auto p=points.equal_range(boost::make_tuple(3,3));
points.erase(p.first,p.second);
Joaquín M López Muñoz
  • 5,243
  • 1
  • 15
  • 20
  • Okay, but I was wondering what this signature is for `size_type erase(key_param_type x)`. I found it in the preprocessed code. Is there no way to call it with a composite_key? – Jörg Richter Sep 25 '12 at 11:21
  • Another thing: erase(iterator,iterator) returns an iterator. That can take a long time with hashed indices, can't it? I still would prefer to call erase(key) if its somehow possible. – Jörg Richter Sep 25 '12 at 13:23
  • The reason why erase is not extended to cope with compatible keys is that `template iterator erase(const CK& ck)` would collide with the existing `iterator erase(iterator)` overload in the case that we call `erase(it)` with an object that is *not* an `iterator` but is convertible to `iterator`. A bit pathological, I admit. – Joaquín M López Muñoz Apr 14 '16 at 16:16
  • The problem with hashed containers returning an iterator on `erase` is described at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2023.pdf and affected Boost.MultiIndex until Boost 1.56, when it was fixed (http://www.boost.org/doc/libs/1_60_0/libs/multi_index/doc/release_notes.html#boost_1_56), so you shouldn't worry about this issue anymore. – Joaquín M López Muñoz Apr 14 '16 at 16:27
0

Adding to the previous answer as per your request. You can have it like this:

Point p={3,3};
points.erase(points.key_extractor()(p));

The only problem with this is that it doesn't scale (if Point is expensive to construct.)

Joaquín M López Muñoz
  • 5,243
  • 1
  • 15
  • 20