Erasing map elements by iterator

O

Owen Brydon

Hi,

Is the following code legal? g++ 3.2 barfs on it, although it seems
fine to me.

#include <map>

using std::map;

int main()
{
map<int,int> i;
i[0]=6;
i[54]=2;
map<int,int>::iterator it=i.begin();
while(it!=i.end())
{
if(it->first==0) it=i.erase(it);
else it++;
}
return 0;

}

The error message from g++ is:
tmp.cpp:13: no match for `std::_Rb_tree_iterator<std::pair<const int,
int>,
std::pair<const int, int>&, std::pair<const int, int>*>& = void'
operator
/usr/include/c++/3.2/bits/stl_tree.h:184: candidates are:
std::_Rb_tree_iterator<std::pair<const int, int>, std::pair<const
int,
int>&, std::pair<const int, int>*>&
std::_Rb_tree_iterator<std::pair<const
int, int>, std::pair<const int, int>&, std::pair<const int,
int>*>::eek:perator=(const std::_Rb_tree_iterator<std::pair<const int,
int>,
std::pair<const int, int>&, std::pair<const int, int>*>&)


As a workaround, is it valid to do the following, or does erasing the
iterator 'tmp' from the map (below) render the iterator 'it' invalid?
#include <map>

using std::map;

int main()
{
map<int,int> i;
i[0]=6;
i[54]=2;
map<int,int>::iterator it=i.begin();
while(it!=i.end())
{
if(it->first==0)
{
map<int,int>::iterator tmp=it;
it++;
i.erase(tmp);
}
else it++;
}
return 0;

}

Regards,

Owen Brydon
 
G

Gianni Mariani

Owen said:
Hi,

Is the following code legal? g++ 3.2 barfs on it, although it seems
fine to me.

#include <map>

using std::map;

int main()
{
map<int,int> i;
i[0]=6;
i[54]=2;
map<int,int>::iterator it=i.begin();
while(it!=i.end())
{
if(it->first==0) it=i.erase(it);
map::erase returns void
else it++;
}
return 0;

}

The error message from g++ is:
tmp.cpp:13: no match for `std::_Rb_tree_iterator<std::pair<const int,
int>,
std::pair<const int, int>&, std::pair<const int, int>*>& = void'
operator

gcc complains it can't find a void assignment ....
As a workaround, is it valid to do the following, or does erasing the
iterator 'tmp' from the map (below) render the iterator 'it' invalid?

The code is fine and likely the only way to do it. A map iterator
remains valid for the life of the map entry.
 
O

Owen Brydon

Ron said:
It's not.
It seems not :)
In this case,
http://www.dinkumware.com/manuals/reader.aspx?b=p/&h=map.html is
incorrect, which is where I got the notion that it returned an iterator.

map::erase returns void.

if(it->first == 0) it.erase(it++); else ++it;

Is this 100% safe? Is the iterator it valid for postincrement after
being erased from the map?

Is the other example I gave where the iterator is copied, then
incremented, then the copy is erased, 100% safe?

Regards,

Owen Brydon
 
G

Guest

It seems not :)
In this case,
http://www.dinkumware.com/manuals/reader.aspx?b=p/&h=map.html is
incorrect, which is where I got the notion that it returned an iterator.

map erase(const key_type&) returns size_type
Is this 100% safe? Is the iterator it valid for postincrement after being
erased from the map?

erase has an iterator argument, postincrement operator ++ applied to map
iterator returns copy of current iterator and increments current iterator.
Is the other example I gave where the iterator is copied, then
incremented, then the copy is erased, 100% safe?

Yes,it is, as well as the shorter version above which does the same.
 
A

Andrew Koenig

map::erase returns void.
Owen> Is this 100% safe? Is the iterator it valid for postincrement after
Owen> being erased from the map?

The example has a typographical error: it.erase(it++) should be
i.erase(it++). With that change, the example is 100% safe:
Although it skates right up to the edge of the broken ice, it
avoids drowning in the frigid water.

The key is that there is a sequence point between evaluating a
function's arguments and calling the function, which means that
before i.erase is called, the value of it has already been
incremented. Therefore, it is no longer referring to the element
that is about to be deleted, and its value therefore remains valid.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top