std::vector の反復と消去
std::vector を反復するための推奨されるアプローチは、反復子を使用することです。ただし、反復中に要素を消去するとイテレータが無効になる可能性があります。
この問題に対処するには、次に示すように、要素を消去した後にイテレータの割り当てを変更することが重要です。
<code class="cpp">for (iterator it = begin; it != end(container) /* !!! */; ) { if (it->somecondition()) { it = vec.erase(it); // Returns the new iterator to continue from. } else { ++it; } }</code>
次のことが重要です。要素を消去した後は毎回コンテナの終わりを再計算する必要があることに注意してください。
より効率的な代替方法は、std::remove_if と Erase():
<code class="cpp">iterator it = std::remove_if(begin, end, pred); vec.erase(it, vec.end());</code>
このアプローチを組み合わせることです。時間計算量を O(N^2) から O(N) に変更します。要素を削除する述語の例を次に示します。
<code class="cpp">struct predicate { bool operator()(const T& pX) const { return pX.shouldIBeRemoved(); } };</code>
特定のケースでは、より一般的なアプローチを使用できます。
<code class="cpp">class remove_by_caller { public: remove_by_caller(AguiWidgetBase* pWidget) : mWidget(pWidget) {} template <typename T> bool operator()(const T& pX) const { return pX.getCaller() == mWidget; } private: AguiWidgetBase* mWidget; };</code>
このアプローチを使用します:
<code class="cpp">std::vector<AguiTimedEvent>::iterator it = std::remove_if(timedEvents.begin(), timedEvents.end(), remove_by_caller(widget)); timedEvents.erase(it, timedEvents.end());</code>
さらに、Boost と C 11 の両方でサポートされているように、ラムダ式を使用するとこのプロセスを簡素化できます。
以上が反復中に `std::vector` から要素を安全に削除するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。