有没有比std::remove_if更好的方法来从向量中移除元素
Is there a better alternative to std::remove_if to remove elements from a vector?
从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
不能改变向量的大小(正如其名称所暗示的那样),因为它只传递迭代器。但包括我在内的许多开发人员一开始都不明白这一点。
那么,有没有一种更安全、更优雅的方式来实现这一点呢?如果没有,为什么?
我发现它不仅难看,而且很容易用错。
别担心,我们一开始都这么做了。
很明显,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;});
这将很快通过std::experimental::erase_if
算法在C++17编译器中可用:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <experimental/vector>
int main()
{
std::vector<int> ints { -1, 0, 1 };
std::experimental::erase_if(ints, [](int x){
return x < 0;
});
std::copy(ints.begin(), ints.end(), std::ostream_iterator<int>(std::cout, ","));
}
打印0,1 的实时示例
相关文章:
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 在 C++ 中输出枚举类类型的向量元素
- 用向量的向量元素初始化向量的空向量
- 为什么不允许使用可变长度数组作为向量元素?
- 在函数中传递向量元素
- 使用 Rcpp 加速替换迭代算法中的列表和向量元素是否合法?
- 返回向量元素的 l 值的正确方法是什么?
- 当向量增长时,指向向量元素的C++指针是否无效
- 如何在C++中从一个向量元素减去std::unorderede_map向量元素并更新它
- C++:向量元素赋值导致访问冲突
- 将向量元素与字符串元素进行比较,而不初始化向量
- 从2D矢量中找出最小尺寸的向量元素的更好方法
- 当我尝试将一个向量元素的值分配给另一个向量元素时,为什么我的应用程序会崩溃
- 使用递归C++向量元素的总和
- 如何查找为数组中的最低值编制索引的向量元素
- 限制指针访问STL ::向量元素
- 访问索引指向向量元素时的seg故障 - 做错了什么
- 如何使用指针访问向量元素的各个元素
- 向量元素数据损坏了Find()操作
- 将字符值分配给向量元素.C