On Thursday, 8 December 2016 at 21:46:26 UTC, Jonathan M Davis wrote:
However, at least as of C++98, non-copyable elements in a
container were not allowed IIRC, so it would have been pretty
rare to have a C++ iterator that returned a non-copyable value
when you dereferenced it.

Even if it was uncommon, i doubt anyone actually made a copy of the dereferenced iterator. There were also no restrictions in place that every algorithm needed it to be copyable, only the ones that actually needed it.
In the case of C++, dereferencing an iterator was basically free.
As an iterator was essentially a pointer and there were no special iterators.

Also, it pretty much _is_ assumed that

auto h = r.front;

is cheap, and there are plenty of cases where calling front
multiple times for the same range would incur additional
overhead, because front is calculated rather than simply
returning a value (e.g. this is what happens with map).
So, it could be a definite performance hit in general to start
insisting that r.front be called without the value being
assigned somewhere.

No one suggested calling front multiple times as a fix. Part of the problem with D is an old one and one that comes up often. There are no rvalue references. This means it's a pain in the ass to write generic code. There's no easy way to write code that
will work for both references and values.

As an example you can write the following in C++:

    int  foo0() { return 10; }
    int& foo1() { static int i; return i; }

const int& a = foo0(); // a copy is made on the stack, this ref points to it const int& b = foo1(); // this ref points to the global variable in foo1()

in D:

    int     foo0() { ... }
    ref int foo1() { ... }

    auto a = foo0();  // a copy is made
    auto b = foo1();  // a copy is made
auto c = &foo1(); // need to write different code to get the result we want

    void callback(ref int);

    callback(a); // ok
    callback(b); // ok
    callback(c); // nope

The problem lies with D's inability to write generic code that works in boths instances. This means writing the same code twice
in some instances, or just not supporting one of the methods.


Yes, not allowing copyable elements for ranges is a problem.
But allowing them would also be a big problem.

Not if one of the biggest and most reoccurring complaints with D was fixed.

What we should ultimately do about it, I don't know, but I
think that it's pretty clear that the majority of code would be
better off if non-copyable elements for ranges were not
allowed. And it _is_ possible to work around the problem by
doing as H.S. Teoh suggested and using ranges of pointers.

I don't think so. There's a lot of functions that work with non-copyable elements. Without modifying any code, the only blockage is caused by isInputRange.
Oh well, custom build of phobos it is.


Reply via email to