ループを変更しながら繰り返すことは、一般的に注意が必要です。
したがって、非連想シーケンスで使用できる特定の C++ イディオムがあります。それは、erase-remove イディオムです。
remove_if
アルゴリズムの使用とerase
メソッドの範囲オーバーロードを組み合わせます。
myQueue.erase(
std::remove_if(myQueue.begin(), myQueue.end(), /* predicate */),
myQueue.end());
ここで、述語は、典型的なファンクター オブジェクトとして、または新しい C++11 ラムダ構文を使用して表現されます。
// Functor
struct OddKey {
bool operator()(std::pair<int, int> const& p) const {
return p.first % 2 != 0;
}
};
/* predicate */ = OddKey()
// Lambda
/* predicate */ = [](std::pair<int, int> const& p) { return p.first % 2 != 0; }
ラムダ形式はより簡潔ですが、自己文書化 (名前なし) が少なく、C++11 でのみ使用できます。好みや制約に応じて、最も適したものを選択してください。
コードの書き方を向上させることができます: Boost.Rangeを使用します。
typedef std::vector< std::pair<int, int> > PairVector;
void pass(PairVector& pv) {
auto const filter = [](std::pair<int, int> const& p) {
return p.first % 2 != 0;
};
auto const transformer = [](std::pair<int, int> const& p) {
return std::make_pair(p.first, p.second / 2);
};
pv.erase(
boost::transform(pv | boost::adaptors::filtered( filter ),
std::back_inserter(pv),
transformer),
pv.end()
);
}
transform
およびfiltered
アダプターは、他の多くのドキュメントとともに見つけることができます。