auto ref is on the docket

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Sun Jun 21 23:23:34 PDT 2015


On Monday, 22 June 2015 at 05:25:57 UTC, Walter Bright wrote:
> The idea is that fun(5) would be lowered to:
>
>    auto tmp = 5;
>    fun(tmp);

That's not what Andrei described (though it's what I would have 
expected us to do). Rather, Andrei seems to be suggesting that 
having an auto ref parameter would result in defining both a ref 
and non-ref overload of the function (with the non-ref one 
forwarding to the ref one), which would unfortunately result in a 
combinatorial explosion of function definitions (just like the 
templated version does, except that all of the overloads would 
just forward to the one which took all refs, and all of the 
overloads would always exist regardless of whether they were 
called). So, I'm inclined to think that what you just suggested 
makes a lot more sense than what Andrei suggested.

> But when talking to Andrei I didn't realize that it would be 
> subtly different behavior than 'auto ref' for template 
> functions, which makes me concerned that this is not a good 
> idea.

I don't see how there's any way around that given that the 
behavior of the templated auto ref pretty much depends on the 
function being templated, though Andrei's suggestion comes a lot 
closer than having the compiler insert a variable for you. Also, 
by reusing auto ref for this rather than coming up with a new 
attribute, we can't declare templated functions with the same 
behavior as the non-templated ones would get for auto ref (though 
that's a lot more important IMHO if we implement it via 
introducing a variable rather than introducing overloads, since 
then we'd be able to avoid the template bloat in the cases where 
you're just trying to accept both lvalues and rvalues and don't 
care about forwarding refness).

> Note that one can always rewrite:
>
>     ref int fun(ref int x);
>
> into:
>
>     ref int fun()(auto ref int x);
>
> if auto ref is desired.

Yes, but to be honest, the way that Andrei is suggesting that we 
implement this is so close to just templatizing the function that 
the only benefit to it I see over the status quo is that it would 
work with virtual functions, whereas the templated version 
obviously won't. I really think that we should consider 
implementing this via _one_ function where all of the auto ref 
parameters are lowered to ref, and variables are added where 
necessary by the compiler rather than implementing it via 
lowering it to a combinatorial explosion of overloads.

And if we _do_ implement this via a single function with the 
compiler adding variables rather than having the compiler add 
overloads, I really think that we should consider introducing a 
new attribute for this so that we can use it with templated 
functions and avoid all of the template bloat that we get with 
auto ref right now. There are cases where auto ref is exactly 
what you want, but there are plenty of cases where folks use it 
just so that they can have their function accept both lvalues and 
rvalues, and in that case, all of the extra template 
instantiations are just bloat. So, if we had @anyref or whatever 
we wanted to call it, we could use it both with templated and 
non-templated functions, and we would avoid the confusion 
introduced by having auto ref mean different things for templated 
and non-templated functions. Yes, that would mean introducing 
another attribute, which kind of sucks, but its use is specific 
enough that I think that it would be worth having, and I fully 
expect that it would be a big help in reducing template bloat in 
many programs - especially from those folks who keep clamoring 
for C++'s const& in D.

- Jonathan M Davis


More information about the Digitalmars-d mailing list