Move semantics for D
Jonathan M Davis
jmdavisProg at gmx.com
Fri Jul 13 15:26:45 PDT 2012
On Friday, July 13, 2012 14:11:44 monarch_dodra wrote:
> But I still feel that the internal call to opSlice/copy is really
> a just trap disguised as a safety net...
Yeah. Kind of.
The thing is that there's no way around the fact that structs and arrays are
effectively value types as far as ranges go, whereas classes are reference
types. If you want them to be copied consistently, you need to use save. If
you don't care whether a copy is made or not, then you don't worry about it.
But foreach has to be treated specially with ranges anyway, because of
strings.
foreach(e; str) {}
is going to iterate over char, not dchar, whereas strings are ranges of dchar.
So, if you iterate over a range generically, you need to do
foreach(ElementType!R e; range) {}
So, you have to be careful with foreach already, and having it _not_ save but
having it copy the range automatically (and therefore implicitly saving for
non-reference type forward ranges) is completely consistent with how it works
with passing ranges to functions, so in that sense, it really isn't all that
bad. If anything, things are _more_ consistent that way.
The only way to really solve the save problem would be to disallow forward
ranges which were reference types (which you could mostly do by disallowing
classes, but I don' think that there's any real way to statically check
whether a struct is a reference type or not). Then save wouldn't be needed,
and ranges would all function the same as long as no one made structs which
were reference types into ranges. But that would also cut off some useful
idioms (sometimes, you _want_ a range to be consumed by a function rather than
being implicitly copied - which is why I added std.range.RefRange for 2.060).
So, I don't know of any way to really fix the problem. You need save to make it
possible to copy reference types, and there's no way to reasonably avoid
having to deal with both value type and reference type ranges.
So, we just deal with it. Unfortunately, far too often, the result of that is
that value type ranges work properly and reference type ranges don't, since
range-based functions are usually tested with just value types ranges, but
improved testing fixes that, and that's not all that hard to do.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list