https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107850

--- Comment #4 from Charles-Henri Gros <chgros at synopsys dot com> ---
Looking into it further, there may be an implicit requirement that the
predicate does not modify its argument.
https://eel.is/c++draft/algorithms.requirements#6
"When not otherwise constrained, the Predicate parameter is used whenever an
algorithm expects a function object ([function.objects]) that, when applied to
the result of dereferencing the corresponding iterator, returns a value
testable as true.
In other words, if an algorithm takes Predicate pred as its argument and first
as its iterator argument with value type T, it should work correctly in the
construct pred(*first) contextually converted to bool ([conv]).
The function object pred shall not apply any non-constant function through the
dereferenced iterator.
Given a glvalue u of type (possibly const) T that designates the same object as
*first, pred(u) shall be a valid expression that is equal to pred(*first)."
I'm unfortunately not well-versed enough in C++ legalese to tell what "possibly
const" means in that context, nor "apply any non-constant function".
And while I understand that a "predicate" is generally meant to not do
modification, there are fairly frequent use cases for "apply this potentially
modifying operation, and depending on its result remove the element from the
container". And in practice, this works (e.g. std::remove_if, your own earlier
version of erase_if, other compilers' version...).
Maybe I should go to LEWG and lobby to remove that limitation. In the
meanwhile, I'll probably just keep my own, perhaps slightly less optimal
removal algorithms.

Reply via email to