Range of uncopyable elements

Jerry via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Dec 8 14:32:47 PST 2016


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.




More information about the Digitalmars-d-learn mailing list