rvalue references

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Tue Jun 2 10:06:29 PDT 2015


On Tuesday, 2 June 2015 at 16:02:56 UTC, Namespace wrote:
> Thanks to DIP 25 I think it's time to review this again. I 
> would implement it (if no one else wants to do it), but there 
> are still some unanswered questions:
>
> 1. Is 'auto ref' still the chosen syntax (I guess so)?
> 2. Should auto ref for templates act like auto ref for 
> non-templates (creates a temporary and pass it by ref) or 
> should the current behaviour stay (duplicate the function 2^N 
> times)?
> 3. What's with return ref, should auto ref for non-templates 
> include return ref (like auto ref for templates)?
> 4. What's with this constellation:
>
> struct S { }
>
> void ene(S) { }
> void mene(ref S) { }
> void muh(auto ref S) { }
>
> should 'mene' (ref) interfere with 'muh' (auto ref)?

auto ref with templated functions needs to retain its current 
behavior. Changing it would not only break existing code, but it 
would lose what we have in terms of perfect forwarding (IIRC, 
it's not quite perfect forwarding, but it's close, and we'd be 
much farther from it without auto ref).

If we want to have non-templated functions which can accept both 
rvalues and lvalues without copying the lvalues, then we need 
have a way to mark those parameters so that they're ref and then 
have an invisible, temporary variable inserted to hold a copy of 
an rvalue so that it can be passed by ref and accepted by the 
function as well instead of just accepting lvalues.

If we want that to work with both non-templated and templated 
functions, then we need a new syntax. If we're willing to have 
them work with just non-templated functions, then we could reuse 
auto ref for that (and _maybe_ we could have the compiler 
optimize auto ref on templates to mean the same thing when it can 
determine that it's safe to do so and thus avoid extra template 
instantiations, but I question that that will happen). But then 
we only get it for non-templated functions, and auto ref means 
somethings slightly different for templated and non-templated 
functions, which sucks, but I'm not sure that it's ultimately all 
that big a deal.

I _definitely_ think that it would be a huge mistake for ref in 
general to accept rvalues. If we did that, then suddenly, ref 
would be used everywhere, and you couldn't tell when someone 
wanted to actually set the ref argument to something or whether 
they were just trying to avoid extraneous copies of lvalues. I'd 
much rather have no way to have a parameter accept both rvalues 
and lvalues without copying the lvalues with non-templated 
functions than have ref accept rvalues.

So, basically, I think that we have three options:

1. Do nothing. If you want a function parameter to accept both 
lvalues and rvalues efficently, then either duplicate it with 
various overloads to achieve that or templatize it and use auto 
ref so that the compiler will do that for you.

2. Extend auto ref so that it works with non-templated functions 
by inserting a temporary variable for rvalues so that they can be 
passed to the function by ref. Templated functions stay as they 
are.

3. Add a new attribute - e.g. @rvalue ref - which inserts a 
temporary variable for rvalues so that they can be passed by ref, 
and it works with both templated and non-templated functions.

Right now, we seem to be doing #1, and we have never officially 
decided whether that's permanent. Andrei in particular has 
resisted adding a new attribute, and to some extent, I agree that 
that's undesirable, but it _would_ allow us to solve this problem 
for both templated and non-templated functions, which we can't 
really do otherwise. So, I don't know how reasonable or feasible 
#3 is at this point. #2 probably wouldn't be that hard to get in, 
but then it only works with non-templated functions, and it 
complicates the meaning of auto ref in an already complicated 
language.

Honestly, at this point, I don't know how much this issue really 
matters. It's annoying that we don't have rvalue references, but 
in general, we're living without them just fine, and we're 
heading toward templatizing almost everything for ranges anyway, 
in which case, the current version of auto ref will work just 
fine with most code (though that extraneous template bloat _is_ 
ugly). So, while I'd like to have rvalue references, I also think 
that we can get by just fine without them.

If we _were_ going to add rvalue references, at this point, I'd 
probably lean towards a new attribute, because it's cleaner and 
more flexible that way, but it _does_ mean adding a new 
attribute, and I don't know if that's worth it.

- Jonathan M Davis


More information about the Digitalmars-d mailing list