この問題に関する以前の議論で、std::vector::erase を呼び出すと次のようなエラーが発生することは誰もが知っています。削除された要素 の後にある のみを無効にします。しかし、要素を削除した後、その位置にある反復子はまだ有効ですか (もちろん、削除後は end() を指しません)。
ベクトルの実装方法を理解すると、この反復子が間違いなく使用できることがわかりますが、これが未定義の動作を引き起こすかどうかはわかりません。
例として、次のコードはベクトルからすべての奇数の整数を削除します。このコードは未定義の動作を引き起こしますか?
<code class="cpp">typedef std::vector<int> vectype; vectype vec; for (int i = 0; i < 100; ++i) vec.push_back(i); vectype::iterator it = vec.begin(); while (it != vec.end()) { if (*it % 2 == 1) vec.erase(it); else ++it; }</code>
このコードは私のマシンでは正常に動作しますが、だからといってそれが有効であるとは思えません。
ではありません; 消去に渡された反復子以降のすべての反復子は無効になります。
ただし、erase は、削除された要素の後の要素 (そのような要素がない場合は最後) を指す新しい反復子を返します。この反復子を使用して反復を再開できます。
奇数の要素を削除するこの方法は非常に非効率であることに注意してください。要素が削除されるたびに、それ以降のすべての要素がベクトル内で 1 つ左にシフトされる必要があります (これは O(n2 ))。 Erase-Remove イディオムを使用すると、このタスクをより効率的に (O(n)) 実行できます。 is_odd 述語を作成できます:
<code class="cpp">bool is_odd(int x) { return (x % 2) == 1; }</code>
次に、それをremove_ifに渡すことができます:
<code class="cpp">vec.erase(std::remove_if(vec.begin(), vec.end(), is_odd), vec.end());</code>
以上が検討できる記事のタイトルは次のとおりです。 **イテレータが指す要素を削除するときに、「std::vector::erase()」の後にイテレータを使用しても安全ですか?** タイトルは率直な質問であり、要素を削除した後もその要素を指す反復子を引き続き使用できるかどうかを検討する記事の内容を正確に反映しています。 その他のオプションは次のとおりです。 * **私の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。