反復中に std::vector から消去
std::vector を反復処理し、この条件で v[i] メソッドを使用すると、イテレータの無効化により予期しない動作が発生する可能性があります。この問題に効果的に対処するには、イテレータを使用した適切な反復手法を採用することをお勧めします。
1 つの方法は、新しいイテレータを返す Erase() メソッドを使用することです。これにより、必要な要素の追跡を失うことなく反復を継続できるようになります。
<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(N2) 時間の複雑さを置き換えます。より効率的な O(N) 操作で要素を個別に処理します。 Erase() オペレーションは、remove_if オペレーションによってマークされた要素を削除します。
特定のケースでは、削除条件をチェックするカスタム述語を作成できます:
<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; }; std::vector<AguiTimedEvent>::iterator it = std::remove_if(timedEvents.begin(), timedEvents.end(), remove_by_caller(widget)); timedEvents.erase(it, timedEvents.end());</code>
これらの手法を採用すると、反復プロセスの整合性を損なうことなく、反復中に std::vector から要素を効率的に消去できます。
以上が反復中に `std::vector` から要素を安全に消去するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。