Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > STL NewbieQ: Remove entry from multimap and keep scanning

Reply
Thread Tools

STL NewbieQ: Remove entry from multimap and keep scanning

 
 
John Mills
Guest
Posts: n/a
 
      06-22-2004
Hello -

I'm using STL's 'multimap' type and wish to remove multimap entries for
which 'second' matches some test, roughly as follows:

multimap<type1, type2> mm;
multimap<type1, type2>::iterator pos;
...
for(pos = mm.begin(); pos != mm.end(); ++pos)
if (mytest(pos->second)) {
mm.erase(pos);
break;
}
...

This _should_ work because I expect only one matching map entry at any one
time, but I wondered how to keep looking for more matches, _after_ having
erased the element at 'pos'. Is the iterator still useful after my
'erase'? (My reference says the multimap 'erase' is of type 'void', unlike
[say] for a vector.)

TIA from a Newbie.

- John Mills
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      06-22-2004

"John Mills" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...
> Hello -
>
> I'm using STL's 'multimap' type and wish to remove multimap entries for
> which 'second' matches some test, roughly as follows:
>
> multimap<type1, type2> mm;
> multimap<type1, type2>::iterator pos;
> ...
> for(pos = mm.begin(); pos != mm.end(); ++pos)
> if (mytest(pos->second)) {
> mm.erase(pos);
> break;
> }
> ...
>
> This _should_ work because I expect only one matching map entry at any one
> time,


Right.

> but I wondered how to keep looking for more matches, _after_ having
> erased the element at 'pos'. Is the iterator still useful after my
> 'erase'?


No, and so calling ++pos after an erase is an error.

> (My reference says the multimap 'erase' is of type 'void', unlike
> [say] for a vector.)
>


Simple, increment pos before you call erase, not afterwards. The simplest
way is this

for(pos = mm.begin(); pos != mm.end(); )
if (mytest(pos->second)) {
mm.erase(pos++);
} else {
++pos;
}

john


 
Reply With Quote
 
 
 
 
Pete C.
Guest
Posts: n/a
 
      06-22-2004
John Mills wrote:
> Hello -
>
> I'm using STL's 'multimap' type and wish to remove multimap entries
> for which 'second' matches some test, roughly as follows:
>
> multimap<type1, type2> mm;
> multimap<type1, type2>::iterator pos;
> ...
> for(pos = mm.begin(); pos != mm.end(); ++pos)
> if (mytest(pos->second)) {
> mm.erase(pos);
> break;
> }
> ...
>
> This _should_ work because I expect only one matching map entry at
> any one time, but I wondered how to keep looking for more matches,
> _after_ having erased the element at 'pos'. Is the iterator still
> useful after my 'erase'? (My reference says the multimap 'erase' is
> of type 'void', unlike [say] for a vector.)
>
> TIA from a Newbie.
>
> - John Mills
> (E-Mail Removed)


Try std::remove_if:

struct ShouldRemove
{
int something;
ShouldRemove(int n) : something(n) {}
bool operator() (std:air<int, int>& p)
{
if(p.second == something)
return true;
else
return false;
}
};

// remove all items where second is 123
mm.erase(std::remove_if(mm.begin(), mm.end(), ShouldRemove(123)), mm.end());

- Pete


 
Reply With Quote
 
Julie
Guest
Posts: n/a
 
      06-22-2004
John Harrison wrote:
> No, and so calling ++pos after an erase is an error.
>
> Simple, increment pos before you call erase, not afterwards. The simplest
> way is this
>
> for(pos = mm.begin(); pos != mm.end(); )
> if (mytest(pos->second)) {
> mm.erase(pos++);
> } else {
> ++pos;
> }
>
> john


Isn't:

mm.erase(pos++);

and

mm.erase(pos);
++pos;

the same?
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      06-22-2004

"Julie" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> John Harrison wrote:
> > No, and so calling ++pos after an erase is an error.
> >
> > Simple, increment pos before you call erase, not afterwards. The

simplest
> > way is this
> >
> > for(pos = mm.begin(); pos != mm.end(); )
> > if (mytest(pos->second)) {
> > mm.erase(pos++);
> > } else {
> > ++pos;
> > }
> >
> > john

>
> Isn't:
>
> mm.erase(pos++);
>
> and
>
> mm.erase(pos);
> ++pos;
>
> the same?


Not at all. In the first case pos is incremented before erase is called (but
the old value of pos is passed to erase). In the second pos is incremented
after the call to erase.

This often confuses, but it is the case that arguments to a function must be
evaluated before the function is called, that applies to the post increment
operator just as much as anything else.

john


 
Reply With Quote
 
P.J. Plauger
Guest
Posts: n/a
 
      06-22-2004
"Pete C." <(E-Mail Removed)> wrote in message
news:rr1Cc.14437$(E-Mail Removed) ink.net...

> Try std::remove_if:
>
> struct ShouldRemove
> {
> int something;
> ShouldRemove(int n) : something(n) {}
> bool operator() (std:air<int, int>& p)
> {
> if(p.second == something)
> return true;
> else
> return false;
> }
> };
>
> // remove all items where second is 123
> mm.erase(std::remove_if(mm.begin(), mm.end(), ShouldRemove(123)),

mm.end());

Nope. remove_if copies the surviving members down in a sequence.
You can't do that inside a multimap.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com


 
Reply With Quote
 
Mats Weber
Guest
Posts: n/a
 
      06-23-2004
In article <(E-Mail Removed)>,
"John Harrison" <(E-Mail Removed)> wrote:

>Simple, increment pos before you call erase, not afterwards. The simplest
>way is this
>
> for(pos = mm.begin(); pos != mm.end(); )
> if (mytest(pos->second)) {
> mm.erase(pos++);


I think you need
break;
here if you want your code to do the same as the OP's.

> } else {
> ++pos;
> }

 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      06-23-2004

"Mats Weber" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> In article <(E-Mail Removed)>,
> "John Harrison" <(E-Mail Removed)> wrote:
>
> >Simple, increment pos before you call erase, not afterwards. The simplest
> >way is this
> >
> > for(pos = mm.begin(); pos != mm.end(); )
> > if (mytest(pos->second)) {
> > mm.erase(pos++);

>
> I think you need
> break;
> here if you want your code to do the same as the OP's.
>


No, the whole point of my post was to explain to the OP how to handle the
case where he wanted to remove more than one item from his map.

john


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
STL multimap castironpi@gmail.com Python 6 05-07-2008 04:36 AM
stl multimap, insert with duplicate keys, is ordering stable? reppisch C++ 6 06-19-2007 09:38 AM
multimap stl Anon C++ 3 12-21-2006 10:26 PM
iterate through an STL multimap Tommo C++ 2 05-22-2006 10:17 AM
is STL multimap "find" order stable? salem.ganzhorn@gmail.com C++ 4 06-25-2005 03:05 AM



Advertisments