そのページには、次のように書かれています。
これにより、すべての反復子と、位置または最初の後の要素への参照が無効になります。
それは消去後にイテレータが有効であることを意味position
しますか?first
(明らかに、for_each ループ中にベクター内のいくつかの項目を削除したいので、私はそれを求めます。)
ありがとうございました。
vector
多くの場合、ループ内で複数のアイテムを削除しようとしている場合、各アイテムに対してremove_if
を使用するよりも、 を使用した方がパフォーマンスが向上します。erase
反復消去ではなく、これを考慮してください。
ただし、質問に答えるには、はい、それらは有効ですがend
、消去によりイテレータが と等しくなる可能性があるため、再度テストする前にイテレータをインクリメントすることに注意してくださいend
。編集: @Erik の回答は、実際には有効ではない可能性があることを示していますが、文言は不明です。
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#414 positon
によるとfirst
、無効と見なす必要があります - 標準の文言は不明確ですが、反復子と参照は1 つの文であり、消去された要素への参照は意味がありません。消去された要素を指す無効化された反復子を消去することは「当然のこと」でした。消去されたイテレータが有効であることに依存することは避けたい - begin()
1 つの要素を持つベクトルから消去する場合、イテレータが突然次の値に等しいことを当然とは思わないend()
反復中に消去する場合は、次の構文を検討してください。
vector<int> items = ...;
for(vector<int>::iterator it = items.begin() ; it != items.end() ; /*inline*/)
{
if(/* should erase*/)
it = items.erase(it);
else
++it;
}
これerase()
は、現在の要素の次の要素へのイテレータを返すために機能します。したがって、消去した場合は「インクリメント」され、それ以外の場合は通常どおりインクリメントされます。ただし、他の人が指摘しているように、これはあまり効率的ではなく (現在の要素の後のすべての要素が前方にコピーされるため)、より良い方法があります。たとえば、Mark B が述べたように、 を使用する方がよい場合がありますremove_if
。
はい。しかし、それらは の前と同じ要素を参照しませんerase()
。その要素は消去されるからです!
と言われていますが、それは間違いです。標準によれば、それらは無効化されます (有効であり続けるためには、存在しなくなった要素を指す必要があるため、これは理にかなっています)。