I found here that lambdas are captured by value. This means that if an algorithm internally uses a second algorithm which accepts the lambda by value, any mutable state of the lambda will not be preserved. I will repost my linked questions example here:
remove_if(begin(values), end(values), [i = 0U, it = cbegin(intervals), end = cend(intervals)](const auto&) mutable {
return it != end && ++i > it->first && (i <= it->second || (++it, true));
})
So at the time of writing my original question remove_if
had implementation defined behavior for a mutable
lambda. Is there a list of what other functions are implementation defined?
Yes, it is. See [algorithms.requirements]:
http://eel.is/c++draft/algorithms#requirements-9
[Note: Unless otherwise specified, algorithms that take function objects as arguments are permitted to copy those function objects freely. Programmers for whom object identity is important should consider using a wrapper class that points to a noncopied implementation object such as reference_wrapper, or some equivalent solution. — end note]