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

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

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-11 04:08:09852ブラウズ

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

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

セットを反復処理し、特定の基準に基づいて削除する必要がある要素が見つかった場合、イテレータへの影響を考慮することが重要です。反復中に要素を削除すると、反復子が無効になり、未定義の動作が発生する可能性があります。

よくある誤解は、反復中にセットから要素を削除すると反復子が無効になり、for ループ内のインクリメントが発生するというものです。未定義の動作があります。ただし、必ずしもそうとは限りません。要素の削除中の反復子の動作は実装に依存し、C 標準に従って定義されていません。

反復中にセットから要素を安全に削除する 1 つのアプローチは、代替ループ構造を使用することです。

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

このコードでは、イテレータは値によって消去操作に渡され、次の要素 (または、最後の要素が削除されました)。このアプローチは C 標準に準拠しており、反復子が有効なままであることが保証されます。

もう 1 つのオプションは、少し冗長ではありますが、要素を消去する前に現在の反復子のコピーを作成することです。

for (auto it = numbers.begin(); it != numbers.end(); ) {
    std::set<int>::iterator current = it++;
    if (*current % 2 == 0) {
        numbers.erase(current);
    }
}

この解決策は、反復子の増分を可能な消去操作から分離し、次の要素を指す反復子が確実に残るようにします。 valid.

特定のコンテナに特別に実装されていない限り、消去操作は通常、削除された要素を超えて、セットに対するすべてのイテレータを無効にすることに注意することが重要です。

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

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