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