On Thursday, 8 December 2016 at 17:29:42 UTC, H. S. Teoh wrote:
The problem is that most range algorithms won't work if `auto h
= r.front;` doesn't compile. Random chunks of std.algorithm
won't work for such a range.
One may argue, of course, that std.algorithm ought to be
fixed... but the root of the problem really is a conceptual
one. The definition of a range was made as an extension of a
C++ iterator, which is basically a wrapped pointer. So `auto h
= r.front;` is assumed to be a cheap copy of a *reference* to
the underlying data, rather than copying the data itself. This
is why most of std.algorithm is written the way it is, and why
isInputRange is defined the way it is. A range of non-copyable
elements in this sense is a poor fit for the range concept; a
better fit would be a range of references to an underlying
container of non-copyable elements. Hence my suggestion of
using pointers.
(In any case, conflating a range with a container is usually a
red flag that there's a conceptual mismatch somewhere.
Unfortunately built-in arrays aren't helping by hiding the fact
that the container is actually GC-managed memory, which isn't
directly visible to the user, thus perpetuating the
misconception that range == container.)
T
Well it's exactly like that for C++ as well. std::copy(Iter, ...)
won't compile if the values aren't copyable. There's no
constraints in C++ either so you get some cryptic error message.
The entire std library is like that.
Assuming that is wrong though, as you aren't copying an iterator
or range you are copying the actual value. What you are confusing
"auto h = r.front;" for is this: "auto rcopy = r;". The D code
"auto h = r.front" is not a cheap operation and the equivalent in
C++ is actually this: "auto h = *iterator;" and one should not
assume it is cheap, cause it isn't. Anyways your comparison with
C++ is off.