called copy constructor in foreach with ref on Range
Stanislav Blinov
stanislav.blinov at gmail.com
Tue Jun 23 03:25:55 UTC 2020
On Tuesday, 23 June 2020 at 02:41:55 UTC, Jonathan M Davis wrote:
> As things stand, uncopyable ranges aren't really a thing, and
> common range idiomns rely on ranges being copyable.
Which idioms are those? I mean, genuine idioms, not design flaws
like e.g. references.
> We'd need some major redesigning to make uncopyable ranges
> work, and personally, I don't think that it's worth the trouble.
Of course we would. Andrei is entertaining changing the whole
input range API. Though he, like you, seems opposed to the idea
of uncopyables.
> The range API has no requirement that the init value of a range
> be empty, and any generic code which relies on such behavior is
> buggy. In the case of classes, it would outright crash, because
> the init value would be null.
Yeah, that's a shame.
> I agree that ideally the range API would require that the init
> state of a range be a valid, empty range, but that's simply not
> how it works right now. In order to make it work that way, we'd
> have to redesign the range API in at least some respects (e.g.
> getting rid of save and making it illegal for classes to be
> forward ranges).
Better yet - making it illegal for classes to be ranges.
> As things stand, it is _not_ true that it's safe to copy
> forward ranges and then use the original. Sure, it will work
> for some ranges, but for others it won't. The entire reason
> that save exists is for ranges that are classes, because
> copying them does not result in an independent range. The range
> API does not require that copying a range result in an
> independent copy. It's not even guaranteed that copying a range
> that's a struct will result in an indpendent copy. Depending on
> the range type, copying it could result in an independent copy,
> or it could result in a reference to to the original range, or
> it could even result in part of the state being copied and part
> of it being a reference (e.g. if the current front is stored
> directly in the range, but the iteration state is stored by
> reference).
If copying isn't making a copy, it's not copying.
> If you rely on copying a range resulting in an independent
> copy, you will have buggy code - even if it's a forward range.
> The _only_ way that the range API specifies that you can get an
> independent copy of a range is to use save, and generic code
> should never rely on any other mechanism for that.
That's exactly what I said. "Copying of forward ranges is
absolutely fine. It's what the current `save()` primitive is
supposed to do."
...Except, of course, that that shouldn't be the case. *Copying*
should be creating a copy. :)
> Now, ideally, we'd get rid of save and require that copying a
> forward range result in an independent copy (which would then
> require that a class be wrapped in a struct to be a range)
Yes!
> but that's simply not how the current range API works.
No, it's not :(
More information about the Digitalmars-d-learn
mailing list