擦除_if在哪里?

发布于 2024-09-13 08:51:54 字数 111 浏览 2 评论 0原文

我有一个容器,想根据谓词删除元素。 erase_if 听起来很熟悉,但我在 C++ 中找不到它。它的名称是什么以及在哪里定义的? 我想在 VS10 中将它与 lambda 一起使用。

I've got a container and would like to erase elements based on a predicate. erase_if sounds familiar, but I can't find it in C++. What's the name and where is it defined?
I'd like to use it with a lambda in VS10.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

我的痛♀有谁懂 2024-09-20 08:51:55

它位于 Library Fundamentals v2 中,很快就会出现在C++20

It's in Library Fundamentals v2, and soon in C++20.

素罗衫 2024-09-20 08:51:55

MSVC 尚未实现 P1209R0 因此,作为一种解决方法,您可以将特定容器的实现从该论文的某处复制到您的代码中。 GCC 9.1 和 Clang 9.0 已经有了它。

namespace std {

// for std::string
template <class charT, class traits, class A, class Predicate>
void erase_if(basic_string<charT, traits, A>& c, Predicate pred) {
    c.erase(remove_if(c.begin(), c.end(), pred), c.end());
}

// for std::deque
template <class T, class A, class Predicate>
void erase_if(deque<T, A>& c, Predicate pred) {
    c.erase(remove_if(c.begin(), c.end(), pred), c.end());
}

// for std::vector
template <class T, class A, class Predicate>
void erase_if(vector<T, A>& c, Predicate pred) {
    c.erase(remove_if(c.begin(), c.end(), pred), c.end());
}

// for std::list
template <class T, class A, class Predicate>
void erase_if(list<T, A>& c, Predicate pred) {
    c.remove_if(pred);
}

// for std::forward_list
template <class T, class A, class Predicate>
void erase_if(forward_list<T, A>& c, Predicate pred) {
    c.remove_if(pred);
}

// for std::map
template <class K, class T, class C, class A, class Predicate>
void erase_if(map<K, T, C, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::multimap
template <class K, class T, class C, class A, class Predicate>
void erase_if(multimap<K, T, C, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::set
template <class K, class C, class A, class Predicate>
void erase_if(set<K, C, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::multiset
template <class K, class C, class A, class Predicate>
void erase_if(multiset<K, C, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::unordered_map
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::unordered_multimap
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::unordered_set
template <class K, class H, class P, class A, class Predicate>
void erase_if(unordered_set<K, H, P, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::unordered_multiset
template <class K, class H, class P, class A, class Predicate>
void erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

} // namespace std

MSVC does not yet implement C++20's std::erase_if from P1209R0 so, as a workaround, you can just copy the implementation for specific container from that paper somewhere to your code. GCC 9.1 and Clang 9.0 already have it.

namespace std {

// for std::string
template <class charT, class traits, class A, class Predicate>
void erase_if(basic_string<charT, traits, A>& c, Predicate pred) {
    c.erase(remove_if(c.begin(), c.end(), pred), c.end());
}

// for std::deque
template <class T, class A, class Predicate>
void erase_if(deque<T, A>& c, Predicate pred) {
    c.erase(remove_if(c.begin(), c.end(), pred), c.end());
}

// for std::vector
template <class T, class A, class Predicate>
void erase_if(vector<T, A>& c, Predicate pred) {
    c.erase(remove_if(c.begin(), c.end(), pred), c.end());
}

// for std::list
template <class T, class A, class Predicate>
void erase_if(list<T, A>& c, Predicate pred) {
    c.remove_if(pred);
}

// for std::forward_list
template <class T, class A, class Predicate>
void erase_if(forward_list<T, A>& c, Predicate pred) {
    c.remove_if(pred);
}

// for std::map
template <class K, class T, class C, class A, class Predicate>
void erase_if(map<K, T, C, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::multimap
template <class K, class T, class C, class A, class Predicate>
void erase_if(multimap<K, T, C, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::set
template <class K, class C, class A, class Predicate>
void erase_if(set<K, C, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::multiset
template <class K, class C, class A, class Predicate>
void erase_if(multiset<K, C, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::unordered_map
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::unordered_multimap
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::unordered_set
template <class K, class H, class P, class A, class Predicate>
void erase_if(unordered_set<K, H, P, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

// for std::unordered_multiset
template <class K, class H, class P, class A, class Predicate>
void erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred) {
    for (auto i = c.begin(), last = c.end(); i != last; )
        if (pred(*i))
            i = c.erase(i);
        else
            ++i;
}

} // namespace std
凉栀 2024-09-20 08:51:55

我猜您正在考虑 remove_if采用谓词来确定是否应该删除该元素。

remove_if 返回一个迭代器,该迭代器指向容器中要删除的元素的开头。要真正删除它们,您需要使用erase

container.erase(remove_if(container.start(), container.end(), pred), container.end())

要么是这样,要么您错误地回忆了copy_if算法?它以某种方式被排除在标准之外,但在 Effective STL 中编写并实现。

I'm guessing you're thinking of remove_if which takes a predicate to determine if the element ought to be removed.

remove_if returns an iterator pointing to the beginning of the elements to remove in the container. To actually remove them you need to use erase:

container.erase(remove_if(container.start(), container.end(), pred), container.end())

Either that or perhaps you mistakenly recalled the copy_if algorithm? Which somehow got left out of the standard but was written about - and implemented - in Effective STL.

少女净妖师 2024-09-20 08:51:55

实际上,Boost 库中存在一个名为 erase_if 的方法,用于 指针容器

Actually there exists a method called erase_if in the Boost library for pointer containers.

峩卟喜欢 2024-09-20 08:51:55

对于新的 C++ 20 格式,您可以像这样使用它:

vector<int> vec {1,2,3,4,5};
auto no_of_removed_elements = std::erase_if(vec,[](const int a){return a==5;});

指向参考的链接。

With the new C++ 20 format you can use it like this:

vector<int> vec {1,2,3,4,5};
auto no_of_removed_elements = std::erase_if(vec,[](const int a){return a==5;});

Link to the reference.

小耗子 2024-09-20 08:51:55

有一个list::remove_if,但不适用于所有容器类。 remove_if 也作为一种算法存在,它可以与从 begin()end() 获取的迭代器一起使用。

There is a list::remove_if, but not for all container classes. remove_if also exists as a algorithm, which can be used with the iterators you can get from begin() and end().

爱的十字路口 2024-09-20 08:51:54

您可能正在寻找 std::remove_if ,采用如下模式:

vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end());

You're probably looking for std::remove_if, in a pattern such as:

vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文