On 23 March 2018 at 16:58, Jonathan M Davis via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > On Friday, March 23, 2018 23:35:29 MattCoder via Digitalmars-d wrote: >> Well, to be honest I still can't understand why would you want to >> pass a RValue as reference. > > Well, it's frequently the case that you don't want to copy an object if you > don't have to - especially in the gaming world, where every ounce of > performance matters. If a function accepts an argument by ref, then no copy > is made, but then you have to pass an lvalue, making it really annoying to > call the function when what you have is an rvalue. On the other hand, if the > function doesn't accept its argument by ref, then you can pass an rvalue > (and it will be moved, making that efficient), but then lvalues get copied > when that's often not what you want. C++'s solution to this was rvalue > references.
Ummm... rvalue-references are something completely different. rval-ref's are C++'s solution to move semantics. C++ just simply accepts rvalues passed to const& args. It makes a temp and passes the ref, as you expect. > That way, as long as the parameter is const, it can accept both > rvalues and lvalues, and it won't copy unless it has to. The closest > analogue that D has to this is auto ref, which requires templates, which may > or may not be acceptable. auto-ref == template function, which by definition is NOT an extern(C++) function. auto-ref may also resolve to NOT a ref, which means a move... data structures that are large (ie, a vector or matrix) still have to copy a bunch of memory, even if the copy is algorithmically 'cheap'. > In many cases, it works great, whereas in others, > it doesn't work at all (e.g. virtual functions), and it can result in > template bloat. And templates, that's another case where it fails. auto-ref is something else unrelated to this topic, and it's useful in a different set of cases for a different set of uses/reasons. It's got nothing to do with this. > The whole situation is complicated by the fact that sometimes it's actually > faster to pass by value and copy the argument, even if it's an lvalue. The api author wouldn't have made the arg a ref in that case. > Passing by const& can often result in unnecessary copies if anywhere in the > chain passes the object by value, whereas if it's passed by value, the same > object can often be moved multiple times, avoiding any copies**. **avoiding __calls to the copy constructor__. The memory is likely to still be moved around a bunch of times. The case you're thinking of is when values are *returned* by value, in that case, copy elision is possible, and the result can be constructed in place. That's a completely unrelated problem... you don't do return-by-ref ;) > It's my > understanding that prior to C++11, it was considered best practice to pass > by const& as much as possible to avoid copies but that after C++11 (which > added move constructors), it's often considered better to pass by value, > because then in many cases, the compiler can move the object instead of > copying it**. ** Assuming the object is tiny, but has an expensive copy constructor. In the case where an object is large (and has a primitive, or no copy constructor) it doesn't change the situation; you still wanna pass a big thing by ref in all cases; ie, vector/matrix. > So, C++ gives you control over which you do, and it's not > necessarily straightforward as to which you should use (though plenty of > older C++ programmers likely just use const& all over the place out of > habit). D gives you the same set of options; except that passing args by ref is a PITA in D, and ruins your code.