ホームページ >バックエンド開発 >C++ >反復中に std::set から要素を安全に削除するにはどうすればよいですか?

反復中に std::set から要素を安全に削除するにはどうすればよいですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-13 06:38:14761ブラウズ

How to Safely Delete Elements from a std::set While Iterating?

反復中に std::set から要素を削除する: 分析

C では、 std::set コンテナは効率的な保存と取得を提供します。ユニークな要素の。セットを変更する場合、その要素を反復処理し、特定の基準を満たす要素を削除する必要があるシナリオが発生する場合があります。潜在的な落とし穴を回避するには、反復中に要素を削除する微妙なニュアンスを理解することが重要です。

提供されたコード例は、std::set::iterator を使用して反復処理することにより、セットから偶数を削除する試みを示しています。ただし、ループ内で消去するというアプローチでは、イテレータの有効性について疑問が生じます。

C 標準 (セクション 23.1.2.8) では、消去を含むすべての変更操作は、イテレータと消去された要素への参照のみを無効にすることを指定しています。ただし、コンテナ内の他の要素を指すイテレータについては保証されません。

指定されたコードのコンテキストでは、次の実装は標準に準拠し、イテレータの有効性を保証します。

for (auto it = numbers.begin(); it != numbers.end(); ) {
    if (*it % 2 == 0) {
        numbers.erase(it++);
    }
    else {
        ++it;
    }
}

この改訂されたループは、次の位置に進む前に反復子を古い位置に戻す「後置インクリメント」(it) を利用します。したがって、後続の反復のために反復子を維持しながら、直前にアクセスした要素を安全に消去できます。

C 11 の出現により、消去メンバー関数は後続の要素 (または std::set::) に反復子を返します。最後の要素が削除された場合は終了します)。この更新では、より簡潔で洗練されたソリューションが提供されます。

for (auto it = numbers.begin(); it != numbers.end(); ) {
    if (*it % 2 == 0) {
        it = numbers.erase(it);
    }
    else {
        ++it;
    }
}

要約すると、反復中にセットから要素を削除することは直感的に見えるかもしれませんが、潜在的な落とし穴を回避するには反復子の動作と標準仕様を明確に理解する必要があります。ここで説明する実装は C 標準に準拠しており、セットからの要素の予測可能かつ効率的な削除を保証します。

以上が反復中に std::set から要素を安全に削除するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。