从std::vector
或其他容器中删除具有特定属性的元素的任务适用于功能样式实现:为什么要烦扰循环,内存释放和正确移动数据?
然而,在C ++中执行此操作的标准方法似乎是以下习语:
std::vector<int> ints;
...
ints.erase(
std::remove_if(ints.begin(),
ints.end(),
[](int x){return x < 0;}),
ints.end());
此示例从整数向量中删除小于零的所有元素。
我发现它不仅难看而且容易错误使用。很明显std::remove_if
不能改变向量的大小(正如其名称所暗示的那样),因为它只传递迭代器。但是许多开发人员,包括我自己,在开始时都没有这样做。
那么有更安全,更有希望实现这一目标的方式吗?如果没有,为什么?
答案 0 :(得分:24)
我发现它不仅难看而且容易错误使用。
别担心,我们都是在开始时做的。
很明显,std :: remove_if不能改变向量的大小(正如其名称所暗示的那样),因为它只传递迭代器。但是包括我在内的许多开发人员在开始时都没有这样做。
相同。它让每个人感到困惑。这些年前可能不应该被称为remove_if
。后见之明,嗯?
那么有更安全,更有希望实现这一目标的方式吗?
没有
如果没有,为什么?
因为这是从容器中删除项目时保留性能的最安全,最优雅的方法,其中删除项目使迭代器无效。
预测:
我能做什么?
是的,将这个习语包装成一个函数
template<class Container, class F>
auto erase_where(Container& c, F&& f)
{
return c.erase(std::remove_if(c.begin(),
c.end(),
std::forward<F>(f)),
c.end());
}
激励示例中的电话会变成:
auto is_negative = [](int x){return x < 0;};
erase_where(ints, is_negative);
或
erase_where(ints, [](int x){return x < 0;});
答案 1 :(得分:13)
很快就可以通过std::experimental::erase_if
算法在C ++ 17就绪编译器中使用它:
/* CSS */
.CssClassJsLoad .JsHide {
display:none; }
/* For all objects within both of these classes: Do not display.
Remember: the <html>-tag only gets the class "CssClassJsLoad" if JS is present or respectively successfully executed. So if JS is not present, display will be standard as "block" element */
打印0,1 的