[英]C++ std::set::erase with std::remove_if
This code has the Visual Studio error C3892
.此代码具有 Visual Studio
error C3892
。 If I change std::set
to std::vector
- it works.如果我将
std::set
更改为std::vector
- 它可以工作。
std::set<int> a;
a.erase(std::remove_if(a.begin(), a.end(), [](int item)
{
return item == 10;
}), a.end());
What's wrong?怎么了? Why can't I use
std::remove_if
with std::set
?为什么我不能将
std::remove_if
与std::set
?
You cannot use std::remove_if()
with sequences which have const
parts.您不能将
std::remove_if()
与具有const
部分的序列一起使用。 The sequence of std::set<T>
elements are made up of T const
objects. std::set<T>
元素序列由T const
对象组成。 We actually discussed this question just yesterday at the standard C++ committee and there is some support to create algorithms dealing specifically with the erase()
ing objects from containers.我们实际上就在昨天在标准 C++ 委员会上讨论了这个问题,并且有一些支持创建专门处理容器中的
erase()
对象的算法。 It would look something like this (see also N4009 ):它看起来像这样(另见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;
}
}
}
(it would probably actually delegate to an algorithm dispatching to the logic above as the same logic is the same for other node-based container). (它可能实际上委托一个算法调度到上面的逻辑,因为相同的逻辑对于其他基于节点的容器是相同的)。
For you specific use, you can use对于您的特定用途,您可以使用
a.erase(10);
but this only works if you want to remove a key while the algorithm above works with arbitrary predicates.但这仅适用于您想删除键而上述算法适用于任意谓词的情况。 On the other hand,
a.erase(10)
can take advantage of std::set<int>
's structure and will be O(log N) while the algorithm is O(N) (with N == s.size()
).另一方面,
a.erase(10)
可以利用std::set<int>
的结构并且将是 O(log N) 而算法是 O(N) (其中N == s.size()
)。
std::remove_if
re-orders elements, so it cannot be used with std::set
. std::remove_if
重新std::remove_if
元素,因此它不能与std::set
一起使用。 But you can use std::set::erase
:但是你可以使用
std::set::erase
:
std::set<int> a;
a.erase(10);
Starting with C++20, you can use std::erase_if for containers with an erase()
method, just as Kühl explained.从 C++20 开始,您可以将std::erase_if用于具有
erase()
方法的容器,正如Kühl 所解释的那样。 Notice that this also includes std::vector
, as it has an erase method.请注意,这也包括
std::vector
,因为它具有擦除方法。 No more chaining a.erase(std::remove_if(...
:)不再链接
a.erase(std::remove_if(...
:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.