I have to do a trivial iteration of all the elements in a std::map, first to last. On each element I have to perform an operation. Assume that the map contains the following pairs:
map<string,string> farm={
{"one","puppy"},
{"two","kitty"},
{"three","sheepy"}
}
The bit of code that performs the iteration is the following:
for(map<string,string>::iterator beast; beast!=farm.end(); ++beast)
{
feed(*beast);
}
Now the surprise is that the above code works for the first element (puppy
is fed) but the iterator fails to go to the next elements. The debugger shows that ++beast
never returns (seems like it is recursively branching on its left leaf forever).
It seems that the issue here is that beast
is never assigned to farm.begin()
and as such it can't progress to the next item (see first element of the for).
So here are my questions:
Is it normal that the default constructor of a map iterator automatically positions the object to point to the
map.begin()
element?If that is common practice, then why a valid first element is returned (it could have been returned
map.end()
for example) ?How could the
operator++
be allowed to quietly fail in an infinite loop? Wouldn't be better to return with an error code (we disabled exceptions) or fail openly somehow ?
I wonder if the standard allows this kind of behaviours or it is an implementation choice.
Assumptions: I am not using C++11, I am using Green Hills compiler v2016 with execption support disabled
EDIT:
I am trying to understand why I get a valid value and a quiet fail as in other threads people suggest that a default-constructed iterator is assigned to map.end()
. Does the standard gives guidance on this?
No, you should initialize it properly:
Btw there is no way that the compiler can know that you want
map<string,string>::iterator beast
to be an iterator forfarm
, of course you need to get an iterator from the container and not just create an iterator and assume it points to the container you wish.