0

このコード スニペットでは、Update() はブール値を返します。false が返された場合は、ベクターから要素を削除したいと思います。

ただし、これによりデバッグ アサーションが失敗したという実行時エラーが発生します。式は「インクリメントできないベクトル反復子」です。

コード:

for(auto iter = someVector.begin(); iter != someVector.end(); ++iter){
    if(!iter->get()->Update()) iter = someVector.erase(iter);
}

私も次のようにイテレータから減算しようとしました:

for(auto iter = particles.begin(); iter != particles.end(); ++iter){
    if(!iter->get()->Update()) iter = --(particles.erase(iter));
}

...しかし、これにより「ベクトル反復子はデクリメントできません」という結果になります。

コードを意図したとおりに動作させるにはどうすればよいですか。Update() 関数が false を返したときにベクター要素が削除されるようにするには?

4

2 に答える 2

5

ループを次のように変更します。

for(auto iter = someVector.begin(); iter != someVector.end();){
    if(!iter->get()->Update())
        iter = someVector.erase(iter);
    else
        ++it;
}

アサーションの理由は、 への呼び出し後、eraseiterと等しい可能性があるためend()です。によって返されるイテレータeraseはすでに「次」であるため、インクリメントすることは想定されていません。

于 2013-08-17T19:08:29.003 に答える
1

そもそも上記のように使用するのではなく、次のように使用することを勧めします。erase()

someVector.erase(std::remove_if(someVector.begin(), someVector.end(),
                                [](decltype(*someVector.begin()) element){
                                    return !element.get()->update();
                                },
                 someVector.end());

1 つの要素だけを消去する必要がある場合は、 の 1 つの反復子バージョンを使用する場合とほぼ同じですerase()。複数の要素を消去する必要がある場合、コピー/移動が少なくなります。表現しやすいという理由だけでラムダ関数を使用していますが、ラムダ関数が使用できない場合は、適切な関数オブジェクトを使用して同じことができることに注意してください。

于 2013-08-17T19:16:37.557 に答える