4

私はここからスワップアンドポップテクニックを使用しています: Erasing element in a vector while iterating using swap-and-pop

以下のコードは、「ベクトル反復子に互換性がありません」というアサーション エラーが発生します。

for(auto iter=vec.begin(); iter!=vec.end();)
{
    if((*iter).isAlive())//update the entity if the entity is alive
    {
        (*iter).update();
        ++iter;
    }
    else  //otherwise, get rid of it
    {
        std::swap(*iter, vec.back());
        vec.pop_back();
    }
}

ただし、std::vector の代わりに std::list を使用すると、すべて正常に動作します。

ベクトルを使用するとアサーション エラーが発生するのはなぜですか?

4

1 に答える 1

0

vec.pop_back()最後の要素を呼び出すと、iterを指しているため無効になりvec.back()ます。STL ドキュメントによると、 と がvector::pop_back()無効back()になりend()ます。

これを修正する 1 つの方法は、次の特殊なケースを検出することですsize()==1

for(auto iter=vec.begin(); iter!=vec.end(); )
{
    if((*iter).isAlive())//update the entity if the entity is alive
    {
        (*iter).update();
        ++iter;
    }
    else if(vec.size() > 1) // can swap&pop
    {
        std::swap(*iter, vec.back());
        vec.pop_back();
    }
    else // need to reset iterator
    {
        vec.pop_back();
        iter = vec.begin();
    }
}

仮定:

  • auto正しいタイプを推測しています
  • ループ不変式iter!=vec.end()はキャッシュされていません
于 2018-01-29T01:07:39.650 に答える