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

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

Patricia Arquette
リリース: 2025-01-04 15:31:40
オリジナル
487 人が閲覧しました

How to Safely Iterate and Remove Elements from a std::list?

std::list の要素の反復と削除

std::list の反復中に要素を削除するには、慎重な処理が必要です。イテレータの無効化を避けてください。よくある誤解の 1 つは、評価直後に要素を削除すると反復子が正しくインクリメントされると想定することです。ただし、この方法では、「リスト反復子は増分できません」というエラーが発生します。

反復子の動作について

std::list では、要素は連続的に割り当てられます。要素が削除されると、後続の要素が移動して空いたスペースを埋めます。その結果、削除された要素を最初に指していたイテレータは無効になります。この反復子をインクリメントすると、未定義の動作が発生します。

正しいアプローチ: 最初にインクリメントし、後で削除します

反復中に要素を正しく削除するには、次の戦略を採用します:

  1. 最初に反復子をインクリメントします: 移動するには i を使用します何かを削除する前に、次の要素への反復子を実行します。
  2. 前の要素を削除します: items.erase(i ) を使用して、現在の位置より前にあった要素を削除します。ここで i は反復子を返します。次の要素へ。あるいは、 i = items.erase(i); を使用することもできます。

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;
    }
}
ログイン後にコピー

この変更コードはリストを反復処理し、次のようにします:

  1. 各アイテムに対して update() を呼び出します。
  2. アイテムの場合非アクティブな場合は、それを削除し、反復子を次の要素に移動します。
  3. 項目がアクティブな場合は、他のコードを実行し、反復子をインクリメントします。

Remove_if アプローチの回避

元のコードには、ループの後に Remove_if() 呼び出しが含まれていました。この方法では、リストに対する追加のパスが必要となるため、このような状況では通常は推奨されません。上に示したように、1 回のパスで反復と削除を行うことは、より効率的でシンプルなソリューションです。

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

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