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