0

I'd like to delete some element out of a boost multi-index container by erasing iterators while visiting the collection.

What I am not sure about is if any iterator invalidation is involved and whether my code below would invalidate firstand last iterators.

If the code below is incorrect, which is the best way considering the specific index (ordered_unique) below?

 #include <iostream>
 #include <stdint.h>
 #include <boost/multi_index_container.hpp>
 #include <boost/multi_index/ordered_index.hpp>
 #include <boost/multi_index/key_extractors.hpp>
 #include <boost/shared_ptr.hpp>

  using namespace std;

  class MyClass{
  public:  
    MyClass(int32_t id) : id_(id) {}
    int32_t id() const
    { return id_; }
  private:  
    int32_t id_;
  };

  typedef boost::shared_ptr<MyClass> MyClass_ptr;

  typedef boost::multi_index_container<
      MyClass_ptr,
      boost::multi_index::indexed_by<
        boost::multi_index::ordered_unique<
          boost::multi_index::const_mem_fun<MyClass,int32_t,&MyClass::id>
        >
      >
    > Coll;

  int main() {

    Coll coll;
    // ..insert some entries 'coll.insert(MyClass_ptr(new MyClass(12)));'

    Coll::iterator first = coll.begin();
    Coll::iterator last  = coll.end();

    while(first != last) {
      if((*first)->id() == 3)
        coll.erase(first++);
      else 
        ++first;    
    }  
 }
Abruzzo Forte e Gentile
  • 14,423
  • 28
  • 99
  • 173

1 Answers1

1

The reason that erase for containers returns an iterator is to use that result:

first = coll.erase(first);

Then you don't have to worry about how the underlying implementation handles erase or whether it shifts elements around. (In a vector, for instance, your code would've skipped an element in your iteration) However, the documentation does state that:

It is tempting to see random access indices as an analogue of std::vector for use in Boost.MultiIndex, but this metaphor can be misleading, as both constructs, though similar in many respects, show important semantic differences. An advantage of random access indices is that their iterators, as well as references to their elements, are stable, that is, they remain valid after any insertions or deletions.

Still, just seeing coll.erase(first++) is a flag for me, so prefer to do it the other way.

Barry
  • 286,269
  • 29
  • 621
  • 977