5

ベクトルの反復中に特定の要素を消去したいのですが、以下のコードでは「ベクトル反復子はインクリメントできません」というアサーション エラーが発生します。

for(auto iter=vec.begin(); iter!=vec.end(); ++iter) 
{     
    if((*iter).isDead())
    {        
        std::swap(*iter, vec.back());//swap with the back       
        vec.pop_back();     //erase the element
    } 
} 

このコードの何が問題になっていますか?

4

2 に答える 2

9

その反復で要素を削除しない場合にのみ、反復子をインクリメントする必要があります。

for(auto iter=vec.begin(); iter!=vec.end();) 
{     
    if((*iter).isDead())
    {        
        std::swap(*iter, vec.back());//swap with the back       
        vec.pop_back();     //erase the element
    } 
    else
        ++iter;
}

またはさらに良いことに、ループ全体を次のように置き換えますremove_if

vec.erase(std::remove_if(vec.begin(), vec.end(),
    std::bind(&ValueType::isDead, _1)), vec.end());
于 2012-12-10T15:38:48.587 に答える
7

現在の要素と交換した要素を超えて増分しています。それが最後の要素である場合は、それを消去してイテレータを無効にしました。次のようなものを使用して、消去しなかった場合にのみインクリメントする必要があります。

for(auto iter=vec.begin(); iter!=vec.end();) 
{     
    if((*iter).isDead())
    {        
        std::swap(*iter, vec.back());//swap with the back       
        vec.pop_back();     //erase the element
    } else {
        ++iter;
    }
} 
于 2012-12-10T15:39:50.270 に答える