back

by matt_d·12y ago·view on hn ↗
Thanks for the reply!

Interesting that the constness in `for each` caused confusion (did it offer a `mutable` opt-in, though?), would intuitively expect it to be the POLS behavior. I guess given that you were probably receiving feedback on that, I will take it as something to be acknowledged.

I can see the reference semantics point, in this context the difference from the lambdas seems to make more sense.

// Just to explore another avenue, again mostly out of curiosity :-), how realistic (from the impl. POV) would be to have value-semantic range-based `for` with _mandated_ copy elision whenever possible?

True about `std::for_each`, that's what I've referred to as the "allowance" for the mutable iterators, wasn't aware about the grouping being merely a historical artifact, though. I've always felt a bit dirty using it for mutation[1], it seems that maybe unnecessarily so :-)

// [1] -- perhaps due to the algorithm being specified in terms of the InputIterator concept; hm, that being said, I suppose that while it only guarantees that we can read (dereferenced) `it`, it doesn't say that `it` _itself_ has to be immutable (right?), so it could be that I should think of a better metaphor to internalize. How do you think about InputIterators?

1 comments
> did it offer a `mutable` opt-in, though?

Nope.

> would intuitively expect it to be the POLS behavior.

If you give me (the implementation) a modifiable range, and I invisibly add constness before giving you back an element, that's surprising. C++ doesn't add constness by default anywhere (with the novel exception of lambda function call operators). If you give me a modifiable range, the least surprising thing to do is to give you a modifiable element, because that's what all of ptr[idx], * ptr, and * iter would do.

> how realistic (from the impl. POV) would be to have value-semantic range-based `for` with _mandated_ copy elision whenever possible?

If you say "for (auto elem : range) { elem = stuff; }" the write to the elem-copy will be dropped on the floor. Copy elision can't solve that.

> it doesn't say that `it` _itself_ has to be immutable (right?)

Correct.

> How do you think about InputIterators?

The concept is single-pass, read-only, but a given iterator may be stronger. for_each() is kind of special (it's the only algorithm that takes InputIterators, yet allows stronger iterators to be used with modifying functors), but other algorithms are vaguely similar. For example, transform(InIt first, InIt last, OutIt result, UnOp op) permits transform(first, last, first, op) for an in-place transformation - here, first/last's type clearly has to be InIt and OutIt simultaneously, i.e. a mutable FwdIt iterator or stronger.

Thanks for the explanations!