On Tuesday, 10 November 2015 at 14:28:15 UTC, Shachar Shemesh wrote:
It seems that "foreach" requires that the range be copyable, in direct contradiction to the fact that Range is not a forward range.

To add to what I said, whether a range is "copyable" has nothing to do with whether it is a forward range or not. What's supposed to be guaranteed with any and all ranges is that if you copy it, it has the exact same state as the original had - but _not_ that that state is separate from the original. So, if you have

auto copy = orig;

then you can pop elements off of copy like you would have popped them off of orig, but you must on longer pop elements off of orig. _copy_ is now the range. This is critical when you consider that most ranges will be copied when they're passed to a function. If they weren't copyable, they'd be almost useless.

If you couple that with the extremely amorphous definition of "save" for forward ranges, there seems to be quite a confusion between the two.

There is nothing amorphous about the definition of save. save duplicates a range such that you have two ranges of the same type which are independent of one another and which contain exactly the same elements. save provides a way to get a copy of the range's state regardless of whether it's value type, reference type, or pseudo-reference type.

Consider, for instance, a range which is implemented as a class. It's a full-on reference type, and copying it around will never result in its state being copied. Without save, there would be no way to duplicate it. And save provides the _only_ generic means of duplicating a range. It's a bug any time that generic code depends on the state of a range being duplicated when it's copied. Unfortunately, because most ranges _do_ duplicate their state when they're copied, there's plenty of code out there which is buggy and relies on ranges being duplicated when they're copied. That's why it's so critical to test algorithms with a variety of range types.

- Jonathan M Davis

Reply via email to