1

私はこれらのインスタンスを追跡するクラス Circle を持っています:

Circle *f1;
vector<Circle> list;
vector<Circle>::iterator it;

複数のサークルを作成し、それらを移動させました。Circle の特定のインスタンスを消去するにはどうすればよいですか? たとえば、特定の円が壁にぶつかった場合、それを消去する必要があります。私は他の質問を見回しましたが、彼らが出したコードを試してみましたが、うまくいきませんでした。現時点で私が持っているものは次のとおりです。

for (it = list.begin(); it != list.end(); ++it) {

    it->x += 1;

    if (it->x == ofGetWindowWidth()) {
        list.erase(it);
    }
}

動きの方向を逆にするなど、if ステートメントで動作する他のステートメントを取得しました。list.erase(それ); ここから取得したコード行で、プログラムがクラッシュする理由がわかりません。

4

4 に答える 4

5
for (it = list.begin(); it != list.end(); /* nothing here */) {

    it->x += 1;

    if (it->x == ofGetWindowWidth()) {
        it = list.erase(it);
    } else {
        ++it;
    }
}

元のコードの問題は、要素を消去すると、その要素のイテレータが無効になることです。次にインクリメントしようとしているのとまったく同じイテレータです。これは、未定義の動作を示します。

于 2013-10-28T22:58:46.897 に答える
3

list.eraseは、消去された要素への反復子を無効にします。したがって、「it」が指す要素を消去すると、「it」が無効になり、for ループ本体の後に続く ++it によってプログラムがクラッシュする可能性があります。コードを次のようなものに書き換えると、クラッシュを防ぐことができます。

for(it=list.begin();it!=list.end(); ) {
    //your code
    if(it->x==ofGetWindowWidth())
        it=list.erase(it);
    else
        ++it;
}
于 2013-10-28T22:59:57.147 に答える
2

上記のコードを使用する際の問題は、要素が消去されているときにerase()コンテンツを無効にすることです。itたとえば、代わりにこれを使用できます。

for (it = list.begin(); it != list.end(); ) {
    it->x += 1;

    if (it->x == ofGetWindowWidth()) {
        list.erase(it++);
    }
    else {
        ++it;
    }
}

分岐 usingは、要素を ing する前にerase()、保持された反復子itを現在の場所から移動します。erase()から返された一時オブジェクトのみit++が無効になります。もちろん、このループが機能するために、無条件に をインクリメントすることはできませんit。つまり、非erase()ing ブランチには独自のインクリメントが必要です。

于 2013-10-28T23:00:02.793 に答える
0

で消去を使用できますremove_if。これは、複数の要素の削除にも機能します。あなたの場合、それは

list.erase(std::remove_if(list.begin(), list.end(),
        [](const Circle& c){return c.x == ofGetWindowWidth();},list.end()), 

整数の例:

#include <algorithm>
#include <vector>
#include <iostream>

int main()
{
    std::vector<int> str1 = {1,3,5,7};
    str1.erase(std::remove_if(str1.begin(), str1.end(),
                              [](int x){return x<4 && x>2;}), str1.end());
   for(auto i : str1) std::cout << i ;
}

プリント 157

于 2013-10-28T23:06:12.120 に答える