版权声明:本文为博主原创文章,可以转载但必须注明出处。 https://blog.csdn.net/nirendao/article/details/85885395
很久以前看《Effective STL》看到的。因为有点杂,整理一下。
1. 删除特定值的元素
1.1 序列容器
如vector,deque,string,其删除特定值的元素的方法是使用 erase-remove 用法。
// 对于vector,deque,string,使用 erase-remove 方法
c.erase(remove(c.begin(), c.end(), 999), c.end());
对于list,则直接可以调用remove方法。
// 对于list,直接用 remove 方法
c.remove(999);
1.2 关联容器
即c是set或者map等类型,则使用erase方法。
// 若c是关联容器,直接用erase()
c.erase(999);
2. 删除满足特定条件的元素
先定义一个函数,所有使该函数返回为true的元素都将被删除:
bool predicate(<container element type>);
2.1 序列容器用remove_if
对于序列容器,vector,deque,string,list,把上面的remove换成remove_if就行了:
// 对于 vector,deque,string,使用 erase-remove_if
c.erase(remove_if(c.begin(), c.end(), predicate), c.end());
// 对于list,直接用 remove_if
c.remove_if(predicate);
2.2 关联容器用循环
关联容器没有提供 remove_if 方法,因此需要写一个循环来遍历。
但是注意,当关联容器中的一个元素被删除时,指向该元素的所有迭代器都将失效。一旦执行了c.erase(it),it就变成无效的值。
为了避免这个问题,要确保在调用erase之前,有一个迭代器指向c中的下一个元素:
AssocContainer<int> c;
for (auto it=c.begin(); it!=c.end(); ) {
if (predicate(*it))
c.erase(it++);
else
it++;
}
2.3 序列容器用循环删除
对于序列容器,如果也要通过遍历循环来删除特定的元素,则不能使用上面的删除关联容器特定元素的方法,因为对vector,string,deque这类序列容器来说,调用erase不仅会使指向被删除元素的迭代器失效,而且也会使被删除元素之后的所有迭代器失效。
但是,序列容器的erase()函数的返回值会是下一个元素的迭代器。由此可知,具体方法应如下:
SeqContainer<int> c;
for (auto it=c.begin(); it!=c.end();) {
if (predicate(*it))
it = c.erase(it); // 序列容器的erase()返回被删除元素的下一个元素的迭代器
else
it++;
}
这种方法只对序列容器有效,而对关联容器无效。因为关联容器的erase()方法返回的是void.
(完)