auto ref is on the docket

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Sun Jun 28 00:36:39 PDT 2015


On Sunday, 28 June 2015 at 05:46:11 UTC, Manu wrote:
> On 28 June 2015 at 08:50, Jonathan M Davis via Digitalmars-d 
> <digitalmars-d at puremagic.com> wrote:
>>>
>>> [..]
>>
>>
>> That's what auto ref was originally introduced to do. The 
>> reason that it works only with templates is because Walter 
>> misunderstood what Andrei was proposing. So, it makes sense to 
>> use it for what it was originally intended for and implement 
>> it as proposed with non-templated functions. Now, that has the 
>> downside that we can't use it with templated functions in a 
>> fashion that avoids template bloat,
>
> Stop repeating that. It's not got anything to do with code 
> bloat, you
> can't use it because template auto ref doesn't pass rvalues by 
> ref, it
> passes them by value, which means it's not a ref in any way, 
> and it's
> not what the user wants.
> I can easily get the same behaviour by not-typing 'auto ref', 
> which I
> happily do in all cases that I want something to be passed by 
> value.
> But we're not talking about by-val, we're talking about ref.
>
> It's simple; I want to pass something by value, or I want it to 
> pass by ref... there is no middle ground, it's an explicit 
> binary statement about how the parameter shall be passed. I 
> don't care about lvalues or rvalues. There is no case where I 
> want the compiler to not do the thing I told it to. And if 
> there were a hypothetical case - where ref-ness were dependent 
> on some conditions, I'm confident I could easily express that 
> with existing mechanisms in D. I don't need a weird compiler 
> defined semantic to try and do something smart that turns out 
> never to be what I want.

It makes no sense to pass rvalues by ref. The ref has to refer to 
a memory location so that a pointer can be passed underneath the 
hood, and rvalues don't qualify for that. A temporary variable 
_must_ be created in order to pass an rvalue by ref, even if the 
compiler is able to move the rvalue into the temporary variable 
rather than copy it. So, I don't understand why you would be 
looking to pass rvalues by ref. I can see why you would want to 
pass both rvalues and lvalues to the same function efficiently 
without caring about whether they're rvalues or lvalues, but that 
doesn't necessarily mean ref, and in the case of rvalues, it 
definitely doesn't mean ref.

The most efficient way to pass rvalues is by value, because the 
value can be moved or even simply constructed directly into the 
right place on the stack to begin with. That's why C++11 added 
move constructors and why D has postlblit constructors. That's 
also why it's no longer the advice in C++-land for folks to 
simply always use const& as much as possible (not that it 
shouldn't be used, but whether it should be used or not becomes 
much more complicated). D has moving built-in without the need 
for move constructors, so our situation is simpler, but 
regardless, ref really isn't the answer when it comes to rvalues. 
You _want_ to be passing rvalues by value. It's the lvalues that 
you don't want to pass by value if you're worried about 
efficiency, because they're the ones that are going to have to be 
copied. But still, if what you want is to have rvalues put into a 
place on the stack where they can be passed by ref and then have 
them passed by ref, that's what you'll get with auto ref for 
non-templated functions. It'll pass lvalues by ref, and it'll 
create temporary variables for the rvalues so that they can be 
passed by ref. So, as far as I can tell, auto ref for 
non-templated functions does exactly what you're looking for. 
It's just that it only works for non-templated functions, and 
with the templated ones, rvalues are passed efficiently - but not 
by ref.

- Jonathan M Davis


More information about the Digitalmars-d mailing list