Consistency when removing items from boost multi-index using iterator

I know that the following code is incorrect for std :: vectors and, as a rule, for all STL containers:

std::vector<something>::iterator it = array.begin(); for(; it != array.end(); it++) { ... array.erase(it); ... } 

because the iterator must be updated after erasing and the element.

I was wondering if this would be the same for boost multi-index, for example, would something like the following be correct or not:

 my_index::iterator it = index.get<0>().begin(); for(; it != index.get<0>().end(); it++) { ... index.erase(it); ... } 

I would like to accurately understand the following paragraph of the documentation: http://www.boost.org/doc/libs/1_51_0/libs/multi_index/doc/tutorial/indices.html#guarantees which seems to indicate that I can erase without canceling an iterator. However, I'm not sure that since I am deleting an element, another element that I would have to visit during the iteration could be moved to the current position of the iterator and never be visited (in other words, erasing some elements during the iteration, I’m all Still sure to go through all the elements?).

Thanks!

+4
source share
2 answers

The paragraph you are linking only applies to hashed (unordered) indexes. It states that when new elements are inserted, hashed index iterators remain valid.

When erasing for ordered indices, you can always guarantee a complete iteration using the return value from erase :

 for (; it != index.get<0>().end(); ) { if (...) it = index.erase(it); else ++it; } 

This will also work for hashed (unordered) indexes, since the iteration order is stable over erasing elements.

+6
source

No, your action is not valid in the promotion index. Iterators erased from a collection never remain valid; what can remain valid are other iterators in the collection if you store them somewhere.

Actual text:

Guarantees for the validity of the iterator and the safety of exceptions

Due to the internal restrictions imposed by the Boost.MultiIndex map, hashed indexes provide guarantees for the validity of the iterator and the safety of exceptions, which are actually stronger than required by the standard C ++ Technical Report Library (TR1) regarding unordered associative containers:

The validity of the iterator is preserved in any case during insertion or rehashing: TR1 allows the iterator to be invalid during the transition (implicit or explicit). Erasing an element or a range of elements through iterators is never thrown, since the internal hash of the function and predicate equality objects are not actually called. rehash provides an unmistakable guarantee of the safety of exceptions.

TR1 guarantees only an internal hash function and predicate objects do not throw equality. A somewhat surprising consequence is that a TRU-compliant unordered associative container can erase items if an exception is thrown during renaming! In general, these stronger guarantees play in favor of user convenience, especially as regards the stability of the iterator. A (hopefully minimal) performance degradation can lead to the exchange of goods. Nonetheless.

+3
source

Source: https://habr.com/ru/post/1441235/


All Articles