Where is erase_if?

后端 未结 6 1143
不思量自难忘°
不思量自难忘° 2021-01-07 20:51

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 i

相关标签:
6条回答
  • 2021-01-07 21:17

    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
    
    0 讨论(0)
  • 2021-01-07 21:19

    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());
    
    0 讨论(0)
  • 2021-01-07 21:25

    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.

    0 讨论(0)
  • 2021-01-07 21:36

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

    0 讨论(0)
  • 2021-01-07 21:37

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

    0 讨论(0)
  • 2021-01-07 21:41

    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().

    0 讨论(0)
提交回复
热议问题