読者です 読者をやめる 読者になる 読者になる

コンテナからの要素削除

c++

ひさしぶりに書くとこんな事も忘れてしまっていた.下記のコードでセグメンテーションフォールトが出た. でも,そもそもremove_ifをこんな時には使うようだ.

std::list<int> lis {0,1,2,3,4,5,6,7,8,9};
for (auto itr=lis.begin(); itr!=lis.end(); ++itr) {
  if (*itr == 2)
    lis.erase(itr);
}

どこで出るかと言うと,eraseした後のforループの更新(++itr). lis.erase(itr)でitr(何かしらのアドレスitr)が指す先が消される.と,そのポインタitrもなくなって++itrが出来なくなる? ならばということで,

std::list<int> lis {0,1,2,3,4,5,6,7,8,9};
for (auto itr=lis.begin(); itr!=lis.end(); ) {
  if (*itr == 2)
    lis.erase(itr++); // auto t = itr; itr = itr+1; lis.erase(t)と同じことになる.
  else
    ++itr;
}

もうforっぽくないので,whileで似たように書ける.

std::list<int>::iterator itr = v.begin();
for (itr != v.end()) {
    if (*itr == 2) {
        itr = lis.erase(itr); // eraseの返り値は次のポインタ
    } else ++itr;
}