Why is std::erase(std::erase_if) not a template in <algorithm> that works on any container?

Viewed 174

std::erase(_if) is a nice addition to C++20(finally I can forget about obnoxious erase-remove idiom), but one thing is weird: it is not a generic algorithm in a sense that it only works for std:: containers, e.g. it can not operate on boost vector.

    #include<string>

    #include<vector>

    #include<boost/container/vector.hpp>

    int main() {
        std::string str = " Hello World  !";
        std::erase(str, ' '); // :)
        boost::container::vector<int> vi{1,2};
        std::erase(vi, 2); // :(
    }

My best guess is that the algorithm was in experimental long before concepts were voted in standard so it was a lot of work to rework it, or that there was fear that concept for it could not be specified properly(i.e. it would work incorrectly on some user defined types with funky semantics).

So: my question is why is this not a generic algorithm in with some Concept(or enable_if) requirements/dispatching(e.g. for map/set)?

1 Answers

This is answered in the original proposal, N4009:

Q10. Instead of overloading erase_if() for each container, should you provide a single erase_if(Container&, Predicate) function template that's specified to do the right thing for each container?

A10. Such a general function template could be given user-defined containers. There aren't any "container traits", so it's impossible to determine whether a user-defined container is vector-like, list-like, map-like, or something else. User-defined containers could simply be rejected, but then the general function template wouldn't be doing anything differently than the set of specific overloads being proposed here. Note that an author of a user-defined container can overload erase_if() for their container in their namespace.

TL;DR: because there's no way to write such "Concept(or enable_if) requirements/dispatching".

Related