Hello.
I'm concerned about D's move semantics and how Phobos supports it. For example, std.typecons.Tuple
.
struct A
{
int i;
this(this) { writeln("Expensive copy"); }
}
void main()
{
auto t = Tuple!(A)(A(42));
}
This code produces 1 unnecessary copy. Argument is an rvalue and can be passed by move. Indeed, one copy is elided when rvalue argument binds to constructor parameter, but then it became an lvalue. Take a look at Tuple
constructor.
this(Types values)
{
field[] = values[];
}
Actual fields are constructed from lvalues. Why there is no auto ref
and forward
? It looks like there is no way to construct a tuple without copying.
But it gets even worse, because factory function tuple
creates another level of indirection and produces 2 copies from an rvalue.
C++'s tuples perform perfect forwarding. If class implements a move constructor, then neither tuple's constructor nor make_tuple
produce copies. Example. Price for that is separate move constructor, but at least there is a way to avoid copying.
But this pattern is common in Phobos. This UFCS chain produces 17 copies. But should it?
only(A(0), A(1), A(2))
.filter!(a => a.i == 1)
.takeOne
.front;
So is there no way to utilize move semantics using Phobos? Why forwarding is so neglected?