std::vector イテレータの無効化: 消去後のイテレータの有効性を明らかにする
C の領域では、ベクトル反復子と消去後の行動は混乱の原因となる可能性があります。この問題を詳しく調べるために、次の特定のシナリオを検討します。
消去操作後のイテレータの永続性の検証
直接指すイテレータの有効性に関して関連する疑問が生じます。 std::vector 内の消去された要素に追加します。一般的な概念は、消去された要素の後の位置を指す反復子は無効になるというものです。しかし、疑問は残ります: 消去された要素の正確な位置を指す反復子はまだ有効ですか?
分析と例
この問題を解明するには、次のことを考えてください。次のコード スニペットは、ベクトルから奇数の整数をすべて削除しようとします:
<code class="cpp">vector<int> vec; for (int i = 0; i < 100; ++i) vec.push_back(i); vector<int>::iterator it = vec.begin(); while (it != vec.end()) { if (*it % 2 == 1) vec.erase(it); else ++it; }</code>
このコードは正しく機能しているように見えますが、その妥当性を判断するにはさらに深く掘り下げることが重要です。
質問への回答
その答えは、消去された要素の後の位置を指すイテレータだけでなく、その要素の正確な位置を指すイテレータも無効化することを明確に示しています。
ただし、要素を消去すると、削除された要素の直後、または要素が残っていない場合は最後を指す反復子が返されます。これにより、シームレスな繰り返しの継続が可能になります。
奇数要素の効率的な削除
ここで示したコード スニペットは、奇数要素を削除するための最も効率的な方法ではないことに注意してください。大幅に効率的なアプローチには、カスタム述語を利用して削除する要素を見つけて識別する消去-削除イディオムが含まれます。たとえば、is_odd という述語を定義し、remove_if および Erase とともに使用できます。
<code class="cpp">bool is_odd(int x) { return (x % 2) == 1; } vec.erase(remove_if(vec.begin(), vec.end(), is_odd), vec.end());</code>
これにより、コストのかかる要素の移動が排除され、時間計算量が O(n) に軽減されます。
以上が## `std::vector` 内の消去された要素へのイテレータはまだ有効ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。