1

要素がベクトルであるマップがあります。これらのベクトルから、特別な数に等しいすべての要素を削除する必要があります。num

std::map<size_t,std::vector<size_t> > myMap;
for (std::map<size_t,std::vector<size_t> >::iterator itMap = myMap.begin();itMap != myMap.end();++itMap )
{
    for (std::vector<size_t>::iterator itVec = itMap->second.begin();itVec != itMap->second.end();)
    {
        auto itNextVec = itVec;
        ++itNextVec;
        if (*itVec == num)
        {
            itMap->second.erase(itVec );
        }
        itVec = itNextVec;
    }
}

このコードにより、実行時の例外が発生します。VSでは- vector iterators incompatible。誰かがその原因を指摘できますか?

ありがとう

4

4 に答える 4

9

std::vector::eraseはリストの次の位置に戻るiteratorため、消去を行うときは、イテレータを戻り値と等しくする必要があります。

あなたが考慮しなければならない唯一のことは、返されたものがiterator終わりである可能性があるので、それをチェックする必要があるということです。

私が個人的にやりたいのは、消去を行った後、次のイテレータの位置を取得した後、返されたイテレータの前の位置に戻り、続行を呼び出すことです。for loop

例:

#include <vector>
#include <iostream>

int main()
{
    std::vector<int> myInt;
    myInt.push_back(1);myInt.push_back(2);myInt.push_back(3);

    for(auto iter = myInt.begin();
        iter != myInt.end();
        ++iter)
    {
        if(*iter == 1)
        {
            iter = myInt.erase(iter);
            if(iter != myInt.begin())
            {
                iter = std::prev(iter);
                continue;
            }
        }

        std::cout << *iter << std::endl;
    }
}

ただし、イテレータループ内で消去を実行すると、古いイテレータが無効になり、計画していなかった場合に多くの問題が発生する可能性があるため、嫌われます。

于 2013-02-23T17:01:45.207 に答える
2

消去するとイテレータが無効になります

Iterator validity
Iterators, pointers and references pointing to position (or first) and beyond are 
invalidated, with all iterators, pointers and references to elements before position (or 
first) are guaranteed to keep referring to the same elements they were referring to 
before the call.
于 2013-02-23T16:50:47.597 に答える
1

コレクションを繰り返し処理しているときに、コレクションからアイテムを単純に消去することはできません。少し考えてみてください。itVec「ポイント」するものを削除すると、削除後にitVec要素を「ポイント」しなくなるため、「次の」ポインターがなくなります。

たとえばこの参照を確認すると、erase関数が次の要素への反復子を返すことがわかります。これでループを続けます(もちろん、増やしません)。

于 2013-02-23T16:50:19.340 に答える
1

別のコレクション クラスを使用するかvector、既存のベクターから削除するのではなく、目的のアイテムを削除した新しいベクターを作成することを検討してください。

于 2013-02-23T16:53:34.763 に答える