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 <[email protected]> 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

Reply via email to