Discussion: Rvalue refs and a Move construtor for D

kinke noone at nowhere.com
Wed Sep 4 20:11:33 UTC 2019


On Wednesday, 4 September 2019 at 19:01:54 UTC, kinke wrote:
> Move constructors are in fact never ever used to construct a 
> parameter from an argument. The only time a move ctor is called 
> is for `auto var = std::move(otherVar)`. That's how C++ handles 
> it

I stand corrected, apologies, too much confidence in my human 
memory apparently. According to https://godbolt.org/z/yo2v_V, C++ 
does indeed move-construct a temporary if the parameter is a 
value, not an rvalue ref. So perfect forwarding in the sense of 
simply forwarding the ref really only works if all callees down 
the chain take rvalue refs, so that's the C++ way of preventing 
lots of moving (which is still a lot of copying).

So take the code snippet above as example of how this really 
perfect forwarding could be done in D, without resorting to 
rvalue refs. The state of a moved/forwarded instance would be 
generally impredictable (don't assume it to be T.init, as it 
could have been manipulated by some callee), but that's probably 
not a big deal. It's rather that the destruction might be 
unexpectedly deferred and cause problems:

void caller(S lval)
{
     callee(move(lval)); // pass `lval` by reference under the hood
     assert(lval.x == y); // should not be accessed after moving
     // do some more
} // `lval` alias `param` will be destructed now before returning

void callee(S param) // gets ref to temporary or moved lvalue
{
     param.x = y;
} // nope, `param` is not destroyed right before or after the 
call!


More information about the Digitalmars-d mailing list