std::map - erase 時の iterator の無効化を防ぐ

std::map を使用していると、
「ある条件を満たし(た|てない)要素を削除したい」
ってことがよくある。
そんな時はこんな感じにしてみる。

std::map<int, bool> hige;
std::map<int, bool>::iterator it = hige.begin();
while (it != hige.end()) {
  if (it->second == true) {
    // ここがポイント
    hige.erase(it++);
  } else {
    ++it;
  }
}

[説明]
std::map は要素を変更した場合に、以前まで保持していた iterator は無効になってしまう。
erase の戻り値も void なので何も期待できない。
だったら erase に渡す前の iterator を保持しちゃう。

std::map<int, bool>::iterator tmp = it;
++it;
hige.erase(tmp);

これだと長いので後置インクリメントを使用する。

hige.erase(it++);

後置インクリメントはオブジェクトのコピーが erase の引数になるので、iterator は無効化されない。

これは erase の時点で iterator が無効になるのでエラーになる。

hige.erase(it); it++;