|
|
|
|
|
by betterunix
4689 days ago
|
|
Hair-splitting point: your example is not very good, because for_each is the wrong way to do what you are trying to do. The STL already has the right way to do it: http://www.cplusplus.com/reference/numeric/accumulate/ It is also worth pointing out that you can always thread state through accumulate/reduce/fold and achieve the effect of capturing references / having mutable objects in iteration constructs like for_each. That is how you see things being done in functional languages, and I find myself doing the same in Lisp with some regularity (even though you are generally dealing with references in Lisp; pure functions are usually more readable and less error-prone, at least in my experience). In C++ there is another reason that capture-by-reference is a sensible default: there is no garbage collector. It is up to the programmer to ensure that the lexical environment remains valid for the lifetime of the closure, and so you can only capture locals by value if you return a closure. C++ programmers wind up having to capture smart pointer types by value in that situation anyway, which is basically what I said: if you want to capture by reference, create a reference (or pointer or smart pointer or whatever) and capture the value of the reference itself. |
|
That's true, and it's why we applied the same reasoning to Rust. But we ended up with a very confusing situation. The definition of "closure" in an imperative language really implies capturing by reference; virtually all imperative languages that aren't C++ (or Rust) work this way (in Java it's a little muddy because of the final restriction, which is much maligned because it violates this intuition).
A closure that captures by value just isn't a closure by most programmers' definitions, and I think that the language would be better off treating it as something syntactically different from a closure.