次のコードの背後にある理論的根拠に興味があります。特定のマップについて、end()
次のコードを使用して、(明らかに)までの範囲を削除できますが、これは含まれません。
map<string, int> myMap;
myMap["one"] = 1;
myMap["two"] = 2;
myMap["three"] = 3;
map<string, int>::iterator it = myMap.find("two");
myMap.erase( it, myMap.end() );
これにより、範囲を使用して最後の2つのアイテムが消去されます。ただし、単一のイテレータバージョンの消去を使用した場合myMap.end()
、イテレータは明らかにコレクションの最後にあるため、パスしてもアクションが発生しないと半分は予想していました。これは、明らかに未定義の動作につながる破損または無効なイテレータとは異なります。
しかし、私がこれを行うとき:
myMap.erase( myMap.end() );
セグメンテーション違反が発生します。end()
マップがイテレータが等しいかどうかを確認し、その場合はアクションを実行しないことは難しいとは思いませんでした。私が行方不明になっているこれには微妙な理由がありますか?これでも機能することに気づきました。
myMap.erase( myMap.end(), myMap.end() );
(つまり、何もしません)
私が尋ねる理由は、コレクションへの有効なイテレータを受け取るコードがあり(ただし、そうなる可能性がありますend()
)、最初に次のようにチェックするのではなく、単にこれを消去に渡すことを望んでいたためです。
if ( it != myMap.end() )
myMap.erase( it );
これは私には少し不格好に思えます。別の方法は、キータイプによる消去オーバーロードを使用できるようにコードを書き直すことですが、それを助けることができれば、書き直しすぎないようにします。