6

次のコードを呼び出すときに問題が発生しました。

#include<deque>
using namespace std;

deque<int> deq = {0,1,2,3,4,5,6,7,8};

for(auto it = deq.begin(); it != deq.end(); it++){
    if(*it%2 == 0)
        deq.erase(it);
}

その結果、セグメンテーション違反が発生しました。問題を調べた後、問題はSTLが両端キューのイテレータを管理する方法にあることがわかりました。消去される要素が両端キューの終わりに近い場合、消去された要素を指すために使用されるイテレータは次を指すようになります。要素ですが、前の要素はそうでvector::iteratorはありません。ループ条件をからに変更すると問題が解決する可能性があることは理解してit != deq.end()it < deq.end()ますが、コードが他のコンテナタイプと互換性を持つように、「標準形式」の両端キュー内の特定の要素をトラバースして消去する方法があるかどうか疑問に思います。同じように。

4

2 に答える 2

19

http://en.cppreference.com/w/cpp/container/deque/erase

すべてのイテレータと参照が無効になります[...]

戻り値:最後に削除された要素に続くイテレータ。

これは、ループ内のSTLコンテナから要素を削除する場合の一般的なパターンです。

for (auto i = c.begin(); i != c.end() ; /*NOTE: no incrementation of the iterator here*/) {
  if (condition)
    i = c.erase(i); // erase returns the next iterator
  else
    ++i; // otherwise increment it by yourself
}

または、クリスが言ったように、あなたはただ使うことができますstd::remove_if

于 2013-03-19T02:02:57.197 に答える
11

消去-削除イディオムを使用するには、次のようにします。

deq.erase(std::remove_if(deq.begin(),
                         deq.end(),
                         [](int i) { return i%2 == 0; }),
          deq.end());

必ず利用できるように#include <algorithm>してくださいstd::remove_if

于 2013-03-19T02:19:46.947 に答える