1

重複の可能性:
std :: mapからアイテムをフィルタリングする方法は?
std :: list::eraseが機能しない

std :: listでの削除、消去に関して、いくつかのばかげた質問があります。

私は次のように定義されたクラスを持っています:

class CBase
{
public:
    CBase(int i): m(i)
    {};

    int m;
};

次に、次のように設定します。

list<CBase> ml;
CBase b1(1);
CBase b2(2);
CBase b3(3);
CBase b4(4);
ml.push_back(b1);
ml.push_back(b2);
ml.push_back(b3);
ml.push_back(b4);

m==2のアイテムは;で消去できます。

for (list<CBase>::iterator it=ml.begin(); it!=ml.end(); ++it)
{
    if (it->m == 2)
    {
        ml.erase(it--);
    }
}
    // show what we have now:
for (list<CBase>::iterator it=ml.begin(); it!=ml.end(); it++)
{
    cout << it->m;
}

しかし、私がそうする場合:

for (list<CBase>::iterator it=ml.begin(); it!=ml.end(); it++)
{
    if (it->m == 2)
    {
        ml.erase(it);
        it--;
    }
}

例外があります。どうしてこれなの?

そして、b3を削除したい場合は、

ml.remove(b3);

コンパイルされません。私がオンラインで見つけたすべての例は、もしあれば、list<int>問題なく呼び出すことができます。どうすればそれを機能させることができますか?mylist.remove(3)mylist is list<int>

4

3 に答える 3

2

消去された要素を指しているイテレータを間接参照しています。erase()メンバー関数の戻り値を使用します。

it = ml.erase(it);
// 'it' now points at first element after the last deleted element
于 2013-01-21T15:28:55.673 に答える
1

消去するとイテレータが無効になるためです。デクリメント演算子を含め、使用できなくなります。

編集:削除に関しては、指定した値と等しい値の要素を削除します。std::listを比較に使用しoperator==ます。定義していない限り、コンパイルは失敗します。演算子を定義するだけでOKです。

于 2013-01-21T14:56:48.613 に答える
1

の後、erase渡したイテレータは無効になります。

今、使用して

ml.erase(it--);

イテレータのコピーを渡し、コピーerase後方移動して、リスト内の同じ場所を参照しないようにします。 のコピーが準備された、しかし実際に呼び出される前に発生します。 呼び出し後もイテレータは有効であり、削除した要素の1つ前の位置にあります。
-- erase erase

しかし、あなたがそうするなら

ml.erase(it);
it--;

itはまだ呼び出し後に削除された要素を参照しようとしていますが、無効であるために変更しようとすると例外が発生します。

于 2013-01-21T15:20:47.330 に答える