Reputation: 4253
I was under the impression one cant use erase
on a const iterator
. Check this code.
Why does the below code compile (C++11, gcc)?
long getMax(const bool get_new)
{
long max_val=0;
TO now=getNow();
map<TO, long>& m=get_new?m_new:m_old;
for(auto it=m.cbegin(); it !=m.cend())
{
if(now.compareTime((*it).first)<lookback)
{
max_val=max(max_val,
(*it).second);
++it;
}
else
{
it=m.erase(it);
}
}
return max_val;
}
The map itself is not constant, but my understanding is that the const iterator
should make this fail.
Upvotes: 17
Views: 1485
Reputation: 172984
The behavior has changed from C++11; std::map::erase takes const_iterator
as its parameter.
void erase( iterator pos ); // (until C++11)
iterator erase( const_iterator pos ); // (since C++11)
iterator erase( iterator pos ); // (since C++17)
For std::map::erase
, the passed iterator is just used as the position where the element would be deleted, not for modifying the element through it. That means const_iterator
would be fine. Before C++11, the support for const_iterator
was not very good, but the situation has changed from C++11. You should use const_iterator
instead of iterator
when possible now.
Upvotes: 16
Reputation: 153955
Positions are independent of the constness of their access. It was (is?) quite common that functions doing a search return const_iterator
because they actually do not change the container at all. However, it is desirable to use the obtained position for mutations of the sequences, e.g., to insert()
an element at the corresponding position or to erase()
the located element. As a result, the container where extended to support use of const_iterator
with mutating operations.
It seems the relevant paper is N2350. I'm not sure if this paper is the latest version.
Upvotes: 9