Почему const_iterator может использоваться с std:: map:: erase
У меня было впечатление, что нельзя использовать erase
на const iterator
. Проверьте этот код.
Почему компилируется ниже код (С++ 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;
}
map сам по себе не является постоянным, но я понимаю, что const iterator
должен сделать это сбой.
Ответы
Ответ 1
Поведение изменилось с С++ 11; std:: map:: erase принимает в качестве параметра const_iterator
.
void erase( iterator pos ); // (until C++11)
iterator erase( const_iterator pos ); // (since C++11)
iterator erase( iterator pos ); // (since C++17)
Для std::map::erase
переданный итератор просто используется как позиция, в которой элемент будет удален, а не для изменения элемента через него. Это означает, что const_iterator
будет в порядке. До С++ 11 поддержка const_iterator
была не очень хорошей, но ситуация изменилась с С++ 11. Вы должны использовать const_iterator
вместо iterator
, когда это возможно.
Ответ 2
Позиции не зависят от их доступа. Было (есть?) Довольно часто, что функции, выполняющие поиск, возвращают const_iterator
, потому что они фактически не меняют контейнер вообще. Однако желательно использовать полученную позицию для мутаций последовательностей, например, до insert()
элемента в соответствующем положении или erase()
расположенного элемента. В результате контейнер, который был расширен для поддержки использования const_iterator
с мутировавшими операциями.
Кажется, что соответствующая статья N2350. Я не уверен, что этот документ является последней версией.