1. ホーム
  2. c++

[解決済み】マップを反復しながら削除する方法とは?

2022-04-06 05:53:41

質問

マップを反復しながら削除するには? みたいな感じです。

std::map<K, V> map;
for(auto i : map)
    if(needs_removing(i))
        // remove it from the map

もし私が map.erase イテレータを無効にしてしまいます。

解決方法は?

標準的な連想配列コンテナ消去のイディオムです。

for (auto it = m.cbegin(); it != m.cend() /* not hoisted */; /* no increment */)
{
  if (must_delete)
  {
    m.erase(it++);    // or "it = m.erase(it)" since C++11
  }
  else
  {
    ++it;
  }
}

この場合、通常の for ここでは、コンテナそのものを変更しているため、ループを使用します。範囲ベースのループは、要素にしか関心がないような場合にのみ使用するようにしましょう。RBFLの構文では、ループ本体の内部でコンテナを表示しないことで、このことを明確にしています。

編集する C++11以前は、const-iteratorを消すことができませんでした。そこでは、こう言わなければならないでしょう。

for (std::map<K,V>::iterator it = m.begin(); it != m.end(); ) { /* ... */ }

コンテナから要素を消すことは、その要素の恒常性と矛盾しない。例えて言うなら、昔から delete p ここで p は定数へのポインタです。C++のconst値は存在しなくなる可能性があります。