For Programmers: Free Programming Magazines  


Home > Archive > VC STL > April 2005 > multimap and remove_if









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author multimap and remove_if
Bjarne Nielsen

2005-04-27, 4:02 pm

Hi all

What is the easiest way to remove a number of elements from a multimap, based
on a certain value (not key). The value is a struct, so the items should be
deleted based on the value of a certain field in the struct.

--
Bjarne Nielsen
Igor Tandetnik

2005-04-27, 4:02 pm

"Bjarne Nielsen" <bnielsenIH8SPAM@pc.dk> wrote in message
news:Xns96459CD48339EbnielsenIH8SPAMpcdk
@207.46.248.16
> What is the easiest way to remove a number of elements from a
> multimap, based on a certain value (not key). The value is a struct,
> so the items should be deleted based on the value of a certain field
> in the struct.


I suspect that the easiest way would be a hand-written loop. After a
minute's consideration, I can't think of any standard algorithm that can
be shoehorned into solving this problem, except maybe a rather awkward
use of for_each.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Stoyan Damov

2005-04-27, 4:02 pm

What about calling the map's erase member function on the pair of iterators,
returned by equal_range?

Cheers,
Sotyan

"Bjarne Nielsen" <bnielsenIH8SPAM@pc.dk> wrote in message
news:Xns96459CD48339EbnielsenIH8SPAMpcdk
@207.46.248.16...
> Hi all
>
> What is the easiest way to remove a number of elements from a multimap,
> based
> on a certain value (not key). The value is a struct, so the items should
> be
> deleted based on the value of a certain field in the struct.
>
> --
> Bjarne Nielsen



Stoyan Damov

2005-04-27, 4:02 pm

My bad, I didn't read the question carefully :(

"Stoyan Damov" <stoyan.maps.damov@gmail.com> wrote in message
news:OKyH0GzSFHA.3464@tk2msftngp13.phx.gbl...
> What about calling the map's erase member function on the pair of
> iterators, returned by equal_range?
>
> Cheers,
> Sotyan
>
> "Bjarne Nielsen" <bnielsenIH8SPAM@pc.dk> wrote in message
> news:Xns96459CD48339EbnielsenIH8SPAMpcdk
@207.46.248.16...
>
>



Bjarne Nielsen

2005-04-27, 4:02 pm

"Igor Tandetnik" <itandetnik@mvps.org> wrote in news:efxZLGzSFHA.580
@TK2MSFTNGP15.phx.gbl:

>
> I suspect that the easiest way would be a hand-written loop. After a
> minute's consideration, I can't think of any standard algorithm that can
> be shoehorned into solving this problem, except maybe a rather awkward
> use of for_each.



Thanks for your answer, Igor.

I'll settle for a hand written loop, which I already made, but I thought I
had overseen something obvious.
The problem is, that when an element is deleted, the iterator is invalidated,
and I have to start all over again.

--
Bjarne Nielsen
Igor Tandetnik

2005-04-27, 4:02 pm

"Bjarne Nielsen" <bnielsenIH8SPAM@pc.dk> wrote in message
news:Xns9645A52D680A2bnielsenIH8SPAMpcdk
@207.46.248.16
> I'll settle for a hand written loop, which I already made, but I
> thought I had overseen something obvious.
> The problem is, that when an element is deleted, the iterator is
> invalidated, and I have to start all over again.


Ah, but in a [multi]map, only one iterator is invalidated, all the
others remain valid. So you do something like this:

for (MyMap::iterator it = myMap.begin(); it != myMap.end(); /*
intentionally omitted */)
{
if (needErase(*it))
{
myMap.erase(it++); // **** (1) post-increment important - do not
change
}
else
{
++it;
}
}

Post-increment in (1) is crucial. It is essentially equivalent to this:

MyMap::iterator temp = it;
++temp;
myMap.erase(it);
it = temp;

Even though you erase an element, an iterator pointing to the _next_
element remains valid.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Bjarne Nielsen

2005-04-28, 9:00 am

"Igor Tandetnik" <itandetnik@mvps.org> wrote in news:e3dPekzSFHA.3544
@TK2MSFTNGP10.phx.gbl:

> Ah, but in a [multi]map, only one iterator is invalidated, all the
> others remain valid. So you do something like this:
>
> for (MyMap::iterator it = myMap.begin(); it != myMap.end(); /*
> intentionally omitted */)
> {
> if (needErase(*it))
> {
> myMap.erase(it++); // **** (1) post-increment important - do not
> change
> }
> else
> {
> ++it;
> }
> }
>
> Post-increment in (1) is crucial. It is essentially equivalent to this:
>
> MyMap::iterator temp = it;
> ++temp;
> myMap.erase(it);
> it = temp;
>
> Even though you erase an element, an iterator pointing to the _next_
> element remains valid.


Oh, I see. Thank you very much!

--
Bjarne Nielsen
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com