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

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

DDD
リリース: 2024-12-18 22:59:12
オリジナル
388 人が閲覧しました

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

反復中に std::list から要素を安全に削除する

問題

次のコードを考えてみましょう:

for (std::list<item*>::iterator i = items.begin(); i != items.end(); i++)
{
    bool isActive = (*i)->update();
    // if (!isActive) items.remove(*i);
    // else other_code_involving(*i);
}
items.remove_if(CheckItemNotActive);
ログイン後にコピー

目的は、非アクティブな項目を更新直後にリストから削除し、2 回目のパスの必要性を回避することです。ただし、コメントアウトされた行を使用してループ内の要素を削除しようとすると、「リスト反復子はインクリメントできません」というエラーが発生します。

解決策

反復中に要素を安全に削除するための鍵は、次のとおりです。操作の正しい順序。上記の for ループ手法の代わりに、以下に示すように、コードを while ループに変更する必要があります。

std::list<item*>::iterator i = items.begin();
while (i != items.end())
{
    bool isActive = (*i)->update();
    if (!isActive)
    {
        items.erase(i++);  // alternatively, i = items.erase(i);
    }
    else
    {
        other_code_involving(*i);
        ++i;
    }
}
ログイン後にコピー

最初に反復子 (i ) をインクリメントすることで、反復子は有効なままとなり、反復子を削除するために使用できます。非アクティブな要素。

説明

元の for ループで、items.remove(*i) を使用して要素を削除しようとしています。ループ本体内で反復子 (i) が無効になり、後続の反復が失敗します。 while ループは、要素が削除される前に反復子が更新されることを保証し、後続の反復での有効性を保証します。 items.erase(i ) または i = items.erase(i) を使用すると、適切な要素がリストから削除され、次の有効な要素を指すように反復子が自動的に更新されます。

このアプローチにより、次のことが可能になります。リストを個別にパススルーすることなく、反復中に非アクティブな項目を効率的に削除できます。

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

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート