从一个向量中删除一个符合特定规则的元素用到了,如下的句式:
<span style="font-size:18px;"> vec.erase(
std::remove_if(vec.begin(),vec.end(),RemovePred),
vec.end()
);</span>
erase的这种用法是删除一个区间的元素,但现在要删除的是分布在vec中各处的,百思不得其解。
经查找,在维基百科上找到了答案,翻译如下:
“
一个编程的常见工作就是在容器中删除所有拥有特定值或者符合特定标准的元素。在C++ 中,可以用循环自己实现,但更推荐的做法是用C++标准库来完成。
对此,算法库中提供了romove 和remove_if 算法。因为这些算法在预先给的两个指针上操作,它们并没有容器或集合上的信息。所以,并没有元素被实际删除,而是,所有不符合规则的元素被移动到了序列的开头。相对来说,剩下的元素就是有效的了。但未特别指明的是,在这完成后,remove 算法返回了指向最后一个未被删除的元素的下一个位置的迭代器。
为了实际清除容器中的元素,remove 结合了容器的erase方法,因此称为 ” erase-remove惯用法 "。
”
附上维基百科上的代码备忘。
<span style="font-size:14px;">// Use g++ -std=c++11 or clang++ -std=c++11 to compile.
#include <vector> // the general-purpose vector container
#include <iostream>
#include <algorithm> // remove and remove_if
bool is_odd(int i)
{
return (i % 2) != 0;
}
void print(const std::vector<int> &vec)
{
for (const auto& i: vec)
std::cout << i << ' ';
std::cout << std::endl;
}
int main()
{
// initialises a vector that holds the numbers from 0-9.
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
print(v);
// removes all elements with the value 5
v.erase( std::remove( std::begin(v), std::end(v), 5 ), std::end(v) );
print(v);
// removes all odd numbers
v.erase( std::remove_if(std::begin(v), std::end(v), is_odd), std::end(v) );
print(v);
return 0;
}
/*
Output:
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 6 7 8 9
0 2 4 6 8
*/
</span>