C++ std::set::erase with std::remove_if
C++ std::set::erase with std::remove_if
此代码具有Visual Studio error C3892
。如果我把std::set
改为std::vector
-它工作
std::set<int> a;
a.erase(std::remove_if(a.begin(), a.end(), [](int item)
{
return item == 10;
}), a.end());
怎么了?为什么我不能用std::remove_if
和std::set
?
不能对含有const
部分的序列使用std::remove_if()
。std::set<T>
元素序列由T const
对象组成。实际上,就在昨天,我们在标准c++委员会上讨论了这个问题,并且有一些支持来创建专门处理容器中的erase()
对象的算法。它看起来像这样(参见N4009):
template <class T, class Comp, class Alloc, class Predicate>
void discard_if(std::set<T, Comp, Alloc>& c, Predicate pred) {
for (auto it{c.begin()}, end{c.end()}; it != end; ) {
if (pred(*it)) {
it = c.erase(it);
}
else {
++it;
}
}
}
(它实际上可能会委托一个算法调度上面的逻辑,因为相同的逻辑对于其他基于节点的容器是相同的)。
对于您的特定用途,可以使用
a.erase(10);
,但这只适用于当你想要删除一个键时,而上面的算法适用于任意谓词。另一方面,a.erase(10)
可以利用std::set<int>
的结构,将是O(log N),而算法是O(N)(使用N == s.size()
)。
从c++ 20开始,您可以对具有erase()
方法的容器使用std::erase_if,正如k
// C++20 example:
std::erase_if(setUserSelection, [](auto& pObject) {
return !pObject->isSelectable();
});
注意这也包括std::vector
,因为它有一个擦除方法。没有更多的链接a.erase(std::remove_if(...
:)
std::remove_if
重新排序元素,所以它不能与std::set
一起使用。但是你可以使用std::set::erase
:
std::set<int> a;
a.erase(10);
相关文章:
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- 使用容器中元素的别名删除带有 std::list::remove 的元素是否正确?
- C++代码"x.erase(std::remove(x.begin(), x.end(), ), x.end())"是如何工作的?
- std::remove, std::move(range) and moved-from elements
- 在不同类型的向量上使用 std::remove 的不同结果
- 为什么 std::remove 不删除数组的最后一个元素
- std::remove 和 std::remove_if 设计的稳定性是否失败
- std::unordered_map:渐近{search,insert,remove}性能取决于密钥的大小和数据类型
- std::remove 不起作用
- 为什么std::whatever::erase()是一个方法,std::remove()是独立函数
- std::erase 和 std::remove 组合以删除特定元素不适用于特定示例
- std::remove函数中的转换错误
- 使用 std::erase 和 std::remove 从矢量中删除元素,不使用自定义结构作为值
- vector.erase 和 std::remove 在自定义向量上
- 需要了解 std::remove with vector.erase
- 为什么std::remove不能和std::set一起工作
- 如何为std::list重载std::remove
- std::remove导致编译错误
- Std::remove不是从Std::vector中移除
- 为什么std::remove取迭代器的const版本