I close BIP27. I won't be pursuing BIPs anymore
Atila Neves via Digitalmars-d
digitalmars-d at puremagic.com
Tue Oct 18 13:15:00 PDT 2016
On Tuesday, 18 October 2016 at 18:33:46 UTC, Jonathan M Davis
wrote:
> On Tuesday, October 18, 2016 20:15:18 ag0aep6g via
> Digitalmars-d wrote:
>> 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);
void fun(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
> constructors?
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
T&.
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.
Atila
More information about the Digitalmars-d
mailing list