次のコードを考えてみましょう:
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 サイトの他の関連記事を参照してください。