特定の条件に基づいてマップから要素の範囲を消去しようとしていました。STL アルゴリズムを使用してこれを実行するにはどうすればよいですか?
最初は使用しようと思いましたremove_if
が、remove_if は連想コンテナーでは機能しないため、使用できません。
マップに機能する「remove_if」と同等のアルゴリズムはありますか?
単純なオプションとして、マップをループして消去することを考えました。しかし、マップをループして消去することは安全なオプションでしょうか?(イテレータは消去後に無効になるため)
私は次の例を使用しました:
bool predicate(const std::pair<int,std::string>& x)
{
return x.first > 2;
}
int main(void)
{
std::map<int, std::string> aMap;
aMap[2] = "two";
aMap[3] = "three";
aMap[4] = "four";
aMap[5] = "five";
aMap[6] = "six";
// does not work, an error
// std::remove_if(aMap.begin(), aMap.end(), predicate);
std::map<int, std::string>::iterator iter = aMap.begin();
std::map<int, std::string>::iterator endIter = aMap.end();
for(; iter != endIter; ++iter)
{
if(Some Condition)
{
// is it safe ?
aMap.erase(iter++);
}
}
return 0;
}
ベストアンサー1
ほとんど。
for(; iter != endIter; ) {
if (Some Condition) {
iter = aMap.erase(iter);
} else {
++iter;
}
}
元々持っていたものはイテレータを増分する2回そこから要素を削除した場合、削除する必要のある要素をスキップしてしまう可能性があります。
これは、多くの場所で使用され、文書化されている一般的なアルゴリズムです。
[編集] 消去後にイテレータが無効になるのは正しいですが、消去される要素を参照するイテレータのみが有効であり、他のイテレータは引き続き有効です。したがって、呼び出しiter++
では を使用しますerase()
。