On 8/25/21 7:26 AM, Alexandru Ermicioi wrote:
On Wednesday, 25 August 2021 at 11:04:35 UTC, Steven Schveighoffer wrote:
It never has called `save`. It makes a copy, which is almost always the equivalent `save` implementation.


Really?

Then what is the use for .save method then?
The only reason I can find is that you can't declare constructors in interfaces hence the use of the .save method instead of copy constructor for defining forward ranges.

The `save` function was used to provide a way for code like `isForwardRange` to have a definitive symbol to search for. It's also opt-in, whereas if we used copying, it would be opt-out.

Why a function, and not just some enum? Because it should be something that has to be used, not just a "documenting" attribute if I recall correctly.

Keep in mind, UDAs were not a thing yet, and compile-time introspection was not as robust as it is now. I'm not even sure you could disable copying.


We have now two ways of doing the same thing, which can cause confusion. Best would be then for ranges to hide copy constructor under private modifier (or disable altoghether), and force other range wrappers call .save always, including foreach since by not doing so we introduce difference in behavior between ref and value forward ranges (for foreach use).

There would be a huge hole in this plan -- arrays. Arrays are the most common range anywhere, and if a forward range must not be copyable any way but using `save`, it would mean arrays are not forward ranges.

Not to mention that foreach on an array is a language construct, and does not involve the range interface.

-Steve

Reply via email to