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