Удаление элементов из карты C ++ через цикл for - PullRequest
15 голосов
/ 04 марта 2011

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

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

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

Ответы [ 3 ]

23 голосов
/ 04 марта 2011

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

auto itr = m.begin();
while (itr != m.end()) {
  if (itr->first == 0) {
    m.erase(itr++);
  } else {
    ++itr;
  }
}
11 голосов
/ 04 марта 2011

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

РЕДАКТИРОВАТЬ Мэтью М: этот код правильно сформирован в C ++ 0x и допускается как расширение MSVC.

map<int,int> m;
...
auto itr = m.begin();
while (itr != m.end())
{
    if (itr->second == 0) {
        itr = m.erase(itr);
    }
    else 
    {
        itr++;
    }
}
8 голосов
/ 04 марта 2011

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

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