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

Reply via email to