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.