foreach() behavior on ranges
Joseph Rushton Wakeling
joseph.wakeling at webdrake.net
Wed Aug 25 16:46:54 UTC 2021
On Wednesday, 25 August 2021 at 10:59:44 UTC, Steven
Schveighoffer wrote:
> structs still provide a mechanism (postblit/copy ctor) to
> properly save a forward range when copying, even if the guts
> need copying (unlike classes). In general, I think it was a
> mistake to use `.save` as the mechanism, as generally `.save`
> is equivalent to copying, so nobody does it, and code works
> fine for most ranges.
Consider a struct whose internal fields are just a pointer to its
"true" internal state. Does one have any right to assume that
the postblit/copy ctor would necessarily deep-copy that?
If that struct implements a forward range, though, and that
pointed-to state is mutated by iteration of the range, then it
would be reasonable to assume that the `save` method MUST
deep-copy it, because otherwise the forward-range property would
not be respected.
With that in mind, I am not sure it's reasonable to assume that
just because a struct implements a forward-range API, that
copying the struct instance is necessarily the same as saving the
range.
Indeed, IIRC quite a few Phobos library functions program
defensively against that difference by taking a `.save` copy of
their input before iterating over it.
> What should have happened is that input-only ranges should not
> have been copyable, and copying should have been the save
> mechanism. Then it becomes way way more obvious what is
> happening. Yes, this means forgoing classes as ranges.
I think there's a benefit of a method whose definition is
explicitly "If you call this, you will get a copy of the range
which will replay exactly the same results when iterating over
it". Just because the meaning of "copy" can be ambiguous,
whereas a promise about how iteration can be used is not.
More information about the Digitalmars-d-learn
mailing list