C++erase forループでの使い方

7106 ワード

以前からvectorの中のeraseの方法が少し怪しいことを発見していました()、ちょっと注意しないと、間違います.今日また出会って、いっそ総括して、特に循環体の中でeraseを使う時、vector.begin()とvector.end()は変化するので,誤りの可能性が導入される.
vector<int> veci;
veci.push_back(1);
veci.push_back(2);
veci.push_back(3);
veci.push_back(4);
veci.push_back(5);
veci.push_back(3);
veci.push_back(2);
veci.push_back(3);

for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
      if( *iter == 3)
             veci.erase(iter);
}

このコードを一見すると、普通です.実はこの中には深刻な間違いが隠されています.veciになると.erase(iter)の後、iterは野ポインタになり、野ポインタに対してiter++を行うと間違いになります.
MSDNを表示すると、eraseの戻り値については、An iterator that designates the first element remaining beyond any elements removed,or a pointer to the end of the vector if no such element existsと記述され、コードが変更されます.
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
      if( *iter == 3)
             iter = veci.erase(iter);
}

このコードも間違っています.1)連続する2つの「3」を削除できません.2)3がvectorの最後の位置にある場合もエラー(veci.end()で++操作を実行)
正しいコードは次のとおりです.
for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
{
     if( *iter == 3)
          iter = veci.erase(iter); //               
      else
            iter ++ ;
}