此代码具有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());
Run Code Online (Sandbox Code Playgroud)
怎么了?为什么我不能std::remove_if用std::set?
Die*_*ühl 17
您不能使用std::remove_if()包含const部分的序列.std::set<T>元素序列由T const对象组成.我们昨天在标准的C++委员会中实际上讨论了这个问题,并且有一些支持来创建专门erase()处理来自容器的ing对象的算法.它看起来像这样(另见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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
(它实际上可能会委托一个调度到上面逻辑的算法,因为对于其他基于节点的容器,相同的逻辑是相同的).
对于您的具体用途,您可以使用
a.erase(10);
Run Code Online (Sandbox Code Playgroud)
但这仅适用于上述算法与任意谓词一起使用时删除键的情况.另一方面,a.erase(10)可以利用std::set<int>结构,并且当算法是O(N)(with N == s.size())时将是O(log N ).
小智 11
从 C++20 开始,您可以将std::erase_if用于具有方法的容器erase(),正如K\xc3\xbchl所解释的那样。
// C++20 example:\nstd::erase_if(setUserSelection, [](auto& pObject) {\n return !pObject->isSelectable();\n });\nRun Code Online (Sandbox Code Playgroud)\n请注意,这也包括std::vector,因为它有一个擦除方法。不再需要链接a.erase(std::remove_if(...:)
std::remove_if重新排序元素,因此不能与一起使用std::set。但是您可以使用std::set::erase:
std::set<int> a;
a.erase(10);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6571 次 |
| 最近记录: |