为何std::erase与std::erase_if不支持投影机制?其背后原因是提案因素还是技术局限?
Great question! This is a common point of confusion since Ranges and the std::erase/std::erase_if utilities both landed in C++20, but they feel like they're missing a cohesive feature. Let’s break down why this gap exists:
1. Proposal Timelines & Priorities
First off, the Ranges library (spearheaded by proposal P0896) and the std::erase/std::erase_if functions (from P1209) were developed as separate initiatives for C++20, with different immediate goals:
- The Ranges project was a massive overhaul of the standard algorithm library, focusing on iterator ranges, views, projections, and composability. Its scope was broad and required a lot of work to get right for C++20.
- The
erase/erase_ifutilities were designed to simplify the classic "erase-remove" idiom—saving users from having to write verbose code likecontainer.erase(std::remove(container.begin(), container.end(), value), container.end()). The priority here was to cover all standard containers with basic, easy-to-use functionality first, rather than adding advanced features like projections right out the gate.
2. No Fundamental Technical Barrier
Importantly, there’s no technical reason why std::erase_if couldn’t support projections. Projections are just a way to transform elements before passing them to a predicate—something that could easily be integrated into the erase_if implementation. For example, a hypothetical overload might look like:
template <class Container, class Pred, class Proj> constexpr typename Container::size_type erase_if(Container& c, Pred pred, Proj proj) { // Internally apply the projection to elements before checking the predicate auto it = std::ranges::remove_if(c, [&](const auto& elem) { return pred(std::invoke(proj, elem)); }); auto count = std::distance(it, c.end()); c.erase(it, c.end()); return count; }
This is totally feasible—it just wasn’t part of the initial erase/erase_if proposal.
3. Future Support Is On The Way
The good news is that this gap hasn’t gone unnoticed by the C++ standards committee. Proposal P2009R1 explicitly adds projection support to std::erase_if, and it’s targeted for inclusion in a future C++ standard (likely C23 or later). So we can expect this feature to land eventually—it just didn’t make the cut for the initial C20 release due to scheduling and priority constraints.
In short: The lack of projection support in std::erase/std::erase_if isn’t a technical limitation—it’s a result of separate proposal timelines and prioritizing core functionality first.
内容的提问来源于stack exchange,提问作者NoSenseEtAl

