Consistency when removing items from boost multi-index using an inner iterator
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
On Fri, Nov 20, 2015 at 4:19 PM, Hovnatan Karapetyan
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
, ordered_non_unique >> 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-o... 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.ht...
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
On Fri, Nov 20, 2015 at 4:19 PM, Hovnatan Karapetyan
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
, ordered_non_unique >> 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-o...
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.ht...
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Dominique Devienne
-
Hovnatan Karapetyan