On Tuesday, 18 October 2016 at 18:33:46 UTC, Jonathan M Davis
On Tuesday, October 18, 2016 20:15:18 ag0aep6g via
First, so that people get a nice prepared answer for why D is
different. I can't confidently spell out why D doesn't allow
passing an rvalues in a const ref parameter, and I suspect
that only Andrei really can.
He's explained it several times, but I confess that I've never
really understood the reasoning. I know C++ well but not at the
level of detail that seems to be required to understand what
the exact problem is.
I think I get it; I'm just not sure given the comments that pop
up in the forum. Isn't one of the main reasons distinguishing
between these two?
void fun(ref const Foo);
If they can't be distinguished, you don't get move semantics "for
free". With the current rules:
const Foo foo;
fun(foo); // calls the first one, passes by ref
fun(Foo()); // calls the second one, moves
If rvalues can bind to const, then additional rules for picking
one of the overloads have to be introduced. Even if that were
done simply, I'm pretty sure a lot of people would believe they
were moving when they weren't and vice-versa.
There's a price to pay for the current rules: a possible loss of
performance when passing large structs by value, since moving is
more expensive than putting a pointer in a register (i.e. pass by
ref). I believe this is why Manu wants rvalues to bind to const
ref: to not pay that price.
Though as much as folks like passing rvalues to const ref in
C++, isn't that generally considered to be bad practice now
with C++11/14, because it doesn't play nicely with move
Not really, no. There are cases where passing by value can
generate faster code, but the guideline is still to pass by const
T& as before when T is known. In generic code one should pass by
T&& and std::forward everything. And, of course, if the
performance difference really matters, measure const T& and
by-value and go with whichever is fastest. But, by default, const
As mentioned above, moving is better than copying, but doing
nothing at is usually better than moving.
Or at least, there are many cases where you would
have used const ref previously that now you shouldn't, because
it forces a copy for lvalues in some cases, whereas just
passing by value would allow a move to be made?
Sometimes even the move is elided, similarly to RVO and NRVO.