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.

Reply via email to