3

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?

Roger Lipscombe
  • 89,048
  • 55
  • 235
  • 380
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • Where did you find that this has implementation defined behaviour? I genuinely don't see what part of this would even be implementation defined. – SirGuy Oct 04 '18 at 14:53
  • @SirGuy You can see the problem here: https://stackoverflow.com/questions/41103743/lambda-works-on-latest-visual-studio-but-doesnt-work-elsewhere basically internally to `remove_if`, gcc is using `find_if` which is copying by value. Each copy will create a new copy of `i`, `it`, and `end`. Thus they are not consistently updated. – Jonathan Mee Oct 04 '18 at 14:56
  • @SirGuy It isn't implementation-defined, but for a different reason: There's no requirement for the implementation to **define** it. – Deduplicator Oct 04 '18 at 15:01

1 Answers1

4

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]

Dan M.
  • 3,818
  • 1
  • 23
  • 41
  • So... this is just the quote from the linked answer. I guess we're saying all of them may internally pass by value. – Jonathan Mee Oct 04 '18 at 14:58
  • @JonathanMee yup. "Unless otherwise specified". – Dan M. Oct 04 '18 at 14:59
  • Is there other specification on any of the algorithms though, that's the question? – Jonathan Mee Oct 04 '18 at 15:00
  • 2
    @JonathanMee I didn't see any and I assume there is none since it doesn't make much sense (may needlessly restrict implementation). I'd imagine there are the opposite cases, there the predicate must be copied or be pure (i.e. some parallel algos might not deal nciely with shared mutable state). If you really need to avoid a copy then just use the suggested solution. – Dan M. Oct 04 '18 at 15:05