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