Boost logo

Boost Users :

Subject: Re: [Boost-users] Consistency when removing items from boost multi-index using an inner iterator
From: Hovnatan Karapetyan (hovnatan_at_[hidden])
Date: 2015-11-23 05:17:07


Thanks! I started using your second suggestion: accumulating elements in a
separate container.

hk

On Fri, Nov 20, 2015 at 10:19 PM, Dominique Devienne <ddevienne_at_[hidden]>
wrote:

> 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 mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



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