Boost logo

Boost Users :

Subject: Re: [Boost-users] Consistency when removing items from boost multi-index using an inner iterator
From: Dominique Devienne (ddevienne_at_[hidden])
Date: 2015-11-20 13:19:11


On Fri, Nov 20, 2015 at 4:19 PM, Hovnatan Karapetyan <hovnatan_at_[hidden]>
wrote:

> Hi, I already posted this same question on StackOverflow, since I have not
> gotten an answer yet reposting it here too.
>
> Suppose I am iterating over a boost::multi_index using one of the two
> indices. Then if I start iterating using the other index and erasing an
> element according some criteria, does that invalidate the upper iterator?
>
> E.g.,
>
> struct person {
> string name;
> string last_name;
> string age;}
> typedef multi_index<
> person,
> index_by<
> ordered_non_unique<person, string, &person::name>,
> ordered_non_unique<person, string, &person::age>
> >> PersonCollection;
> PersonCollection pc;
> //insert some elements into pc
> auto index0 = pc.get<0>();auto range0 = index0.equal_range("John");while (range0.first != range0.second) {
> auto index1 = pc.get<1>();
> auto range1 = index1.equal_range(34);
> while (range1.first != range1.second) {
> if (range1.first->last_name == "Smith")
> range1.first = index1.erase(range1.first);
> else
> ++range1.first;
> }
> ++range0.first;}
>
> So in this case, is the range0 iterator always valid? Thanks!
>
http://boost.2283326.n4.nabble.com/Re-multi-index-iterator-invalidation-of-ordered-indezes-after-erase-td2643583.html

BMI iterators remain valid, as long as you don't delete their underlying
element. Which you code can't guarantee I think.
So yes, in your case, I believe it's possible erasing via index1
invalidates your range0.first, or range0.second iterators.
I'm no BMI expert, but you can probably detect such "collisions" by
project()ing [1] your range1.first iterator on index0,
and compare it to range0.first and .second, and respectively increment /
decrement them before doing the .erase().

Although it's probably easier/safer to accumulate which elements to erase
in a separate container, and erase those post iteration, no? --DD

[1]
http://www.boost.org/doc/libs/1_59_0/libs/multi_index/doc/tutorial/basics.html#projection



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net