Удаление элементов из С++-карты через цикл for-loop

Мой STL немного ржавый, так что простите меня за вопрос, возможно, тривиальный вопрос. Рассмотрим следующий фрагмент кода:

map<int,int> m;
...
for (auto itr = m.begin(); itr != m.end(); ++itr) {
    if (itr->second == 0) {
        m.erase(itr);
    }
}

Возникает вопрос: безопасно ли стирать элементы, перемещаясь по карте?

Ответы

Ответ 1

Я думаю, что вы не должны использовать удаленный итератор вообще - в случае списков это вызывает серьезные проблемы, не должно отличаться для карт.

ИЗМЕНИТЬ Matthieu M: этот код хорошо сформирован в С++ 0x и разрешен как расширение с помощью MSVC.

map<int,int> m;
...
auto itr = m.begin();
while (itr != m.end())
{
    if (itr->second == 0) {
        itr = m.erase(itr);
    }
    else 
    {
        itr++;
    }
}

Ответ 2

Да, но не так, как вы это делаете. Вы теряете значение itr при стирании, а затем увеличиваете недействительный итератор.

auto itr = m.begin();
while (itr != m.end()) {
  if (itr->first == 0) {
    m.erase(itr++);
  } else {
    ++itr;
  }
}

Ответ 3

В приведенном примере на самом деле было бы проще использовать перегрузку стирания, которая принимает ключ в качестве аргумента. Эта функция стирает все элементы на карте с заданным ключом (для карты это всегда либо ноль, либо один элемент)

map<int,int> m; 
// ...
m.erase(0); // erase all elements with key equivalent to 0