参考资料显示:
template< class ForwardIt, class UnaryPredicate >
ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPredicate p );
指向旧端点与新端点之间元素的迭代器仍然有效,但是这些元素本身的值未定义。
我尝试了这个简单的程序,以了解他们所说的"未定义的值"是什么意思。
#include <vector>
#include <memory>
#include <iostream>
#include <algorithm>
int main()
{
std::vector< std::shared_ptr<int> > ints;
for (int i = 0; i < 10; ++i)
ints.push_back(std::make_shared<int>(i));
std::remove_if(ints.begin(), ints.end(),
[](const std::shared_ptr<int>& element)
{
return *element % 7 != 0;
});
for (int i = 0; i < 10; ++i)
std::cout << *ints[i] << std::endl;
return 0;
}
输出结果如下:
0
7
2
3
4
5
6
The program has unexpectedly finished.
第七个元素后发生了某些神秘的数据问题,导致了段错误。
有趣的是,可能的实现可以在这里找到。
template<class ForwardIt, class UnaryPredicate>
ForwardIt remove_if(ForwardIt first, ForwardIt last,
UnaryPredicate p)
{
ForwardIt result = first;
for (; first != last; ++first) {
if (!p(*first)) {
*result++ = *first;
}
}
return result;
}
不会产生段错误。
这是一个bug吗?因为迭代器应该是可解引用的。我正在使用gcc 4.7.3。
container.size()
返回相同的值),只有一些元素(被操作删除的那些)是未指定的(根据 C++ 标准)。 - Nawazremove_if
与erase
搭配时要小心。如果你忘记了使用从向量中移除元素的方法,即v.erase(remove_if(...), v.end())
,而只是输入了v.erase(remove_if(...))
- 这将仅删除第一个元素。在此之后,您将得到无效的shared_ptr
。 - Tomasz Gandor