Move construction from !is(T == typeof(this))
Manu via Digitalmars-d
digitalmars-d at puremagic.com
Sun Apr 23 21:21:36 PDT 2017
Are there any known solutions to perform efficient move construction in D?
D's pretty good at doing moves at all the right times, but with a serious
limitation compared to C++ that the type must be an exact match.
Consider this C++; really bad example, but just to illustrate:
struct X { std::string s; };
struct Y {
std::string s;
this(const X &x)
{
s = s; // copy the string, expensive
}
this(X &&x)
{
s = std::move(s); // claim s from x, efficient
}
};
Now, I'm not saying that rval references are the only solution here, just
that I can overload the construction from an X for the rvalue and
non-rvalue case, which is what I want...
I'm thinking in D, this *might* be possible:
struct X {}
struct Y {
this(auto ref X x)
{
static if (__traits(isRef, x))
{
// x is lvalue, copy construct
}
else
{
// x MUST be rvalue(?), move construct
// does this pattern require that I invalidate x the same way C++
does such that X's destructor won't clean up or crash?
}
}
}
Is this solid? I have a vague memory of thinking on this once and realising
there was some edge case where it was logically flawed, but I can't
remember clearly.
Assuming this does work, the next issue is something that mirrors
std::move(), is there already such a thing?
Finally, a further problem exists with auto ref where the function must be
a template. I have cases of code-not-available lib API's where templates
are a problem.
I would prefer to overload 2 constructors for the 2 cases, than have one
template constructor and static if inside. I wonder what would happen in
this case:
struct X {}
struct Y {
this(ref const X x)
{
// x is lvalue reference, copy construct
}
this(X x)
{
// x is an lvalue... which may be a copy of another lvalue. can't move
construct :/
}
}
I guess the question in this case is how overload selection may or may not
work...
I didn't test this, but I expect it's an ambiguous call given an lvalue?
I wonder if this overload set could be made to work such that it is certain
that the non-ref overload is only called with rvalues; ie, given this
ambiguous call, ref is preferred for lvalues. rval can not call ref,
therefore must resolve to byval.
Where is this stuff at?
- Manu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20170424/e0b8551c/attachment.html>
More information about the Digitalmars-d
mailing list