反復中に std::set から要素を削除する: 安全ですか?
セットを反復処理し、特定の基準を満たす要素を削除することは、 C プログラミングの一般的なタスク。ただし、反復中に要素を消去する動作により、反復子の無効化に関する懸念が生じる可能性があります。
提供されたコード スニペットでは、一連の整数を反復処理して偶数を消去します。このコードは動作しているように見えますが、実装固有の動作に依存しています。 C 標準では、反復処理中にセットから要素が消去された場合に何が起こるかを明示的に指定していません。
標準準拠のアプローチ
移植性と信頼性を考慮して、標準に準拠したアプローチの使用を検討してください。
for (auto it = numbers.begin(); it != numbers.end(); ) { if (*it % 2 == 0) { numbers.erase(it++); } else { ++it; } }
このアプローチでは、後置インクリメント演算子 it を使用し、古い反復子を消去しますが、戻る前に次の要素を指すように進めます。その結果、ループは正しく反復され、反復子は各消去操作の後も有効なままになります。
C 11 ソリューション
C 11 では、set の更新された消去メソッドが導入されました。反復中に要素を消去するプロセスを簡素化します:
for (auto it = numbers.begin(); it != numbers.end(); ) { if (*it % 2 == 0) { it = numbers.erase(it); } else { ++it; } }
このアプローチでは、erase メソッドを使用します。これは、消去された要素に続く要素への反復子を返します (最後の要素が消去されている場合は set::end)。これにより、後置インクリメントを使用する必要がなくなり、各消去操作後に有効なままであることが保証されるため、ループが簡素化されます。
結論
最初のコード スニペットは、一部の実装では、実装固有の動作に依存することは一般的に推奨されません。標準に準拠したアプローチまたは C 11 消去メソッドを使用すると、コードが異なるコンパイラやプラットフォーム間で移植可能に正しく動作することを保証できます。
以上が反復中に `std::set` から要素を削除するのは安全ですか?また、それを正しく行う方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。