newbie's questions about multi_index
Hi, I'm currently using multi_index and I have few questions: - I have a multi_index with composed keys, sometimes I need to get a range of items, iterate over them and modify their key. How can I do this properly? sample code: EquivSet::iterator tmp; std::pair<EquivSet::iterator, EquivSet::iterator> es = contains.equal_range(*it); for (EquivSet::iterator it_equiv = es.first; it_equiv != es.second;) if (!X[it_equiv->id]) { tmp = it_equiv++; contains.modify_key(tmp, update_equiv(nbEns)); } else it_equiv++; In this example, the second iterator in the pair, normaly used as end iterator, can be changed and, sometimes, the loop iterates beyond the latter. - If I can choose between a std::set and a multi_index used as a set, which one should I use? Thank you very much for your answers! -- Guillaume Lazzara Epita CSI 2008
Hi Guillaume ----- Mensaje original ----- De: Guillaume Lazzara <glazzara@gmail.com> Fecha: Lunes, Abril 2, 2007 5:13 am Asunto: [Boost-users] newbie's questions about multi_index Para: boost-users@lists.boost.org
Hi,
I'm currently using multi_index and I have few questions:
- I have a multi_index with composed keys, sometimes I need to get a range of items, iterate over them and modify their key. How can I do this properly?
sample code:
EquivSet::iterator tmp; std::pair<EquivSet::iterator, EquivSet::iterator> es = contains.equal_range(*it); for (EquivSet::iterator it_equiv = es.first; it_equiv != es.second;) if (!X[it_equiv->id]) { tmp = it_equiv++; contains.modify_key(tmp, update_equiv(nbEns)); } else it_equiv++;
In this example, the second iterator in the pair, normaly used as end iterator, can be changed and, sometimes, the loop iterates beyond the latter.
Well, I'd say that the potential problem is not that es.second is modified when inside the loop, but rather that elements are repositioned between es.second-1 and es.second, so that the loop revisits them again, right? A solution is to modify the loop so as to not use es.second but the immediately preceding position, just as this (beware, uncompiled code follows): std::pair<EquivSet::iterator, EquivSet::iterator> es = contains.equal_range(*it); if(es.first!=es.second){ EquivSet::iterator last=es.second; --last; EquivSet::iterator next=es.first; EquivSet::iterator it_equiv; do{ it_equiv=next; ++next; contains.modify_key(it_equiv, update_equiv(nbEns)); }while(it_equiv!=last); } Does this work?
- If I can choose between a std::set and a multi_index used as a set, which one should I use?
If you don't use any of the added functionality provided by Boost.MultiIndex (suboject searching, modify(), etc.) using std::set will yield faster compile times. Other than that, a multi_index_container with a single ordered_unique index is entirely equivalent to std::set.
Thank you very much for your answers!
Thank you for using Boost.MultiIndex, good luck with your project, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
Hi, On 4/2/07, "JOAQUIN LOPEZ MU?Z" <joaquin@tid.es> wrote:
Hi Guillaume
----- Mensaje original ----- De: Guillaume Lazzara <glazzara@gmail.com> Fecha: Lunes, Abril 2, 2007 5:13 am Asunto: [Boost-users] newbie's questions about multi_index Para: boost-users@lists.boost.org
Well, I'd say that the potential problem is not that es.second is modified when inside the loop, but rather that elements are repositioned between es.second-1 and es.second, so that the loop revisits them again, right?
A solution is to modify the loop so as to not use es.second but the immediately preceding position, just as this (beware, uncompiled code follows):
std::pair<EquivSet::iterator, EquivSet::iterator> es = contains.equal_range(*it); if(es.first!=es.second){ EquivSet::iterator last=es.second; --last; EquivSet::iterator next=es.first; EquivSet::iterator it_equiv; do{ it_equiv=next; ++next; contains.modify_key(it_equiv, update_equiv(nbEns)); }while(it_equiv!=last); }
Does this work?
Yes, it's perfect! Maybe I didn't see it, but IMHO I think you should include such an example in the multi_index documentation, it would be helpful. :)
- If I can choose between a std::set and a multi_index used as a set, which one should I use?
If you don't use any of the added functionality provided by Boost.MultiIndex (suboject searching, modify(), etc.) using std::set will yield faster compile times. Other than that, a multi_index_container with a single ordered_unique index is entirely equivalent to std::set.
Ok. Thanks again! -- Guillaume Lazzara Epita CSI 2008
participants (2)
-
"JOAQUIN LOPEZ MU?Z"
-
Guillaume Lazzara