在修改循环时进行迭代通常很棘手。
因此,有一个特定的 C++ 习语可用于非关联序列:erase-remove 习语。
它结合了remove_if
算法的使用和方法的范围重载erase
:
myQueue.erase(
std::remove_if(myQueue.begin(), myQueue.end(), /* predicate */),
myQueue.end());
其中谓词表示为典型的仿函数对象或使用新的 C++11 lambda 语法。
// 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; }
lambda 形式更简洁,但可能较少自我记录(无名称),并且仅在 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
适配器,以及许多其他内容。