C std::set::erase 与 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_ifstd::set

原文由 herolover 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 648
2 个回答

您不能将 std::remove_if() 与具有 const 部分的序列一起使用。 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() )。

原文由 Dietmar Kühl 发布,翻译遵循 CC BY-SA 3.0 许可协议

std::remove_if 重新排序元素,因此不能与 std::set 一起使用。但是您可以使用 std::set::erase

 std::set<int> a;
a.erase(10);

原文由 juanchopanza 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题