Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > How to delete stl<map> element from iterator?

Reply
Thread Tools

How to delete stl<map> element from iterator?

 
 
Steve Edwards
Guest
Posts: n/a
 
      02-21-2006
Hi,

After making an iterator to a map and stepping through a loop, I want to
delete any entries that satisfy a test from an external function.

MyMapType::const_iterator iter;

for(iter = m->begin(); iter != m->end(); ++iter)
{
a = iter->first;
b = iter->second;
if ( Test(a,b) == true)
iter->delete?();
}

How do I actually delete the element that iter is pointing to?

Thanks

Steve
 
Reply With Quote
 
 
 
 
Mike Wahler
Guest
Posts: n/a
 
      02-21-2006

"Steve Edwards" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi,
>
> After making an iterator to a map and stepping through a loop, I want to
> delete any entries that satisfy a test from an external function.
>
> MyMapType::const_iterator iter;
>
> for(iter = m->begin(); iter != m->end(); ++iter)


This assumes that 'm' is the name of a pointer to your map,
not of the map itself. I'll keep that assumption below.

> {
> a = iter->first;
> b = iter->second;
> if ( Test(a,b) == true)
> iter->delete?();
> }
>
> How do I actually delete the element that iter is pointing to?


for(iter = m->begin(); iter != m->end(); ++iter)
{
if(condition)
iter = m->erase(iter);
}


An excellent reference for the C++ standard library:
www.josuttis.com/libbook

-Mike



 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      02-21-2006
Steve Edwards wrote:
> After making an iterator to a map and stepping through a loop, I want to
> delete any entries that satisfy a test from an external function.
>
> MyMapType::const_iterator iter;
>
> for(iter = m->begin(); iter != m->end(); ++iter)
> {
> a = iter->first;
> b = iter->second;
> if ( Test(a,b) == true)
> iter->delete?();
> }
>
> How do I actually delete the element that iter is pointing to?


You ask your map to erase it.

Something like

m->erase(iter);

Beware, though, that after erasing the 'iter' becomes invalid. You cannot
increment it after that. You might want to rewrite your loop like this:

for (.... ; ) // no increment at the end
{
a =
b =
if (..
m->erase(iter++);
else
++iter;
}

V
--
Please remove capital As from my address when replying by mail
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      02-21-2006
Mike Wahler wrote:
> if(condition)
> iter = m->erase(iter);


IIRC, 'map::erase' has 'void' return type. Some Standard Library
implementations actually violate that to be consistent with other
(sequential) containers, and probably justifiedly, but generally
speaking your code is ill-formed.

> }
>
>
> An excellent reference for the C++ standard library:
> www.josuttis.com/libbook


Yep. Check out table 6.31 in it.

V
--
Please remove capital As from my address when replying by mail
 
Reply With Quote
 
Mike Wahler
Guest
Posts: n/a
 
      02-21-2006
"Victor Bazarov" <(E-Mail Removed)> wrote in message
news:mrIKf.1333$(E-Mail Removed)01.us.to. verio.net...
> Steve Edwards wrote:


>> How do I actually delete the element that iter is pointing to?

>
> You ask your map to erase it.
>
> Something like
>
> m->erase(iter);
>
> Beware, though, that after erasing the 'iter' becomes invalid. You cannot
> increment it after that. You might want to rewrite your loop like this:


Well, I think we both botched our replies. I forgot the
'else' part, and yours disregards the invalid iterator.

>
> for (.... ; ) // no increment at the end
> {
> a =
> b =
> if (..
> m->erase(iter++);


iter = m->erase(iter);

> else
> ++iter;
> }


-Mike


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      02-21-2006
Mike Wahler wrote:
> "Victor Bazarov" <(E-Mail Removed)> wrote in message
> news:mrIKf.1333$(E-Mail Removed)01.us.to. verio.net...
>
>>Steve Edwards wrote:

>
>
>>>How do I actually delete the element that iter is pointing to?

>>
>>You ask your map to erase it.
>>
>>Something like
>>
>> m->erase(iter);
>>
>>Beware, though, that after erasing the 'iter' becomes invalid. You cannot
>>increment it after that. You might want to rewrite your loop like this:

>
>
> Well, I think we both botched our replies. I forgot the
> 'else' part, and yours disregards the invalid iterator.


Think again.

>
>
>> for (.... ; ) // no increment at the end
>> {
>> a =
>> b =
>> if (..
>> m->erase(iter++);

>
>
> iter = m->erase(iter);
>
>
>> else
>> ++iter;
>> }

>
>
> -Mike
>
>



--
Please remove capital As from my address when replying by mail
 
Reply With Quote
 
Steve Edwards
Guest
Posts: n/a
 
      02-21-2006

>
> Beware, though, that after erasing the 'iter' becomes invalid. You cannot
> increment it after that. You might want to rewrite your loop like this:
>
> for (.... ; ) // no increment at the end
> {
> a =
> b =
> if (..
> m->erase(iter++);
> else
> ++iter;
> }
>
> V


Thanks, but sorry, I don't quite understand. If you say the iterator
becomes invalid, should I break at that point. (in which case I haven't
processed all my elements yet.)
On the other hand, I can't continue if the iterator's invalid, can I?

Steve
 
Reply With Quote
 
Steve Edwards
Guest
Posts: n/a
 
      02-21-2006
In article <0mIKf.2502$(E-Mail Removed) et>,
"Mike Wahler" <(E-Mail Removed)> wrote:

> "Steve Edwards" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > Hi,
> >
> > After making an iterator to a map and stepping through a loop, I want to
> > delete any entries that satisfy a test from an external function.
> >
> > MyMapType::const_iterator iter;
> >
> > for(iter = m->begin(); iter != m->end(); ++iter)

>
> This assumes that 'm' is the name of a pointer to your map,
> not of the map itself. I'll keep that assumption below.
>
> > {
> > a = iter->first;
> > b = iter->second;
> > if ( Test(a,b) == true)
> > iter->delete?();
> > }
> >
> > How do I actually delete the element that iter is pointing to?

>
> for(iter = m->begin(); iter != m->end(); ++iter)
> {
> if(condition)
> iter = m->erase(iter);
> }
>
>
> An excellent reference for the C++ standard library:
> www.josuttis.com/libbook
>
> -Mike




Thanks for the link, it's just what I need.

My compiler is complaining about "iter = m->erase(iter);"

(error: no match for 'operator = ')
 
Reply With Quote
 
TB
Guest
Posts: n/a
 
      02-21-2006
Steve Edwards skrev:
>> Beware, though, that after erasing the 'iter' becomes invalid. You cannot
>> increment it after that. You might want to rewrite your loop like this:
>>
>> for (.... ; ) // no increment at the end
>> {
>> a =
>> b =
>> if (..
>> m->erase(iter++);
>> else
>> ++iter;
>> }
>>
>> V

>
> Thanks, but sorry, I don't quite understand. If you say the iterator
> becomes invalid, should I break at that point. (in which case I haven't
> processed all my elements yet.)
> On the other hand, I can't continue if the iterator's invalid, can I?
>


The statement:

iter++;

increments the iterator and returns the previous position. Compare with

int x = 8, y = 0;
y = x++;
// y = 8, x == 9

so the following

m->erase(iter++);

safely erases the desired element and retains a valid iterator pointing
to the next element or m->end().

--
TB @ SWEDEN
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      02-21-2006
Steve Edwards wrote:
>>Beware, though, that after erasing the 'iter' becomes invalid. You cannot
>>increment it after that. You might want to rewrite your loop like this:
>>
>> for (.... ; ) // no increment at the end
>> {
>> a =
>> b =
>> if (..
>> m->erase(iter++);
>> else
>> ++iter;
>> }
>>
>>V

>
>
> Thanks, but sorry, I don't quite understand. If you say the iterator
> becomes invalid, should I break at that point. (in which case I haven't
> processed all my elements yet.)


Why should you? By passing the value of the post-incremented iterator you
keep it valid. If the 'iter' isn't post-incremented, after 'erase' does
its job, 'iter' cannot be used -- it's invalid. In the proposed code, the
value of 'iter' is passed to 'erase', but _outside_ the object 'iter' is
already pointing to the next element of the map, and therefore is OK.

> On the other hand, I can't continue if the iterator's invalid, can I?


No, if it's invalid, you can't. The whole point of using post-increment
is to keep it valid.

V
--
Please remove capital As from my address when replying by mail
 
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
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
how to Update/insert an xml element's text----> (<element>text</element>) HANM XML 2 01-29-2008 03:31 PM
How to delete array element and add to previous element Al Cholic Ruby 18 07-28-2007 04:56 PM
moving from form element to form element Rod Snyder ASP .Net 1 05-29-2004 01:55 PM
per the active schema, the element <BR> must be included within a parent element MSNews ASP .Net 1 04-22-2004 04:45 PM



Advertisments