On Monday, 22 October 2012 at 11:59:27 UTC, martin wrote:
In the latter overload for rvalues, you aren't given the
original rvalue, but a copy of it!
I need to correct that after a quick test: the rvalue is passed
directly (moved) instead of copying it (well, at least the copy
constructor this(this) is not invoked, even in a debug build);
that makes perfect sense, is efficient and eliminates the need
for C++ rvalue references (T&&).
It doesn't affect the need for an implicit rvalue => const ref
propagation though.
What I'd like to see is the following passing scheme for function
arguments (read-only parameters are denoted by (*)):
lvalue: rvalue:
T: copy move
(*) in T: copy move
out T: pass pointer n/a
ref T: pass pointer n/a
(*) in ref T: pass pointer store on the caller's stack and pass
its address
So only the rvalue passing rule for the "in ref T" case would
need to be implemented. This would allow to use "foo(in ref T
bar)" for lvalues (eliding a copy expected to be costly) as well
as rvalues instead of having to add an overload "foo(in T bar)"
for rvalues. For rvalues, this would actually implicate a
performance hit due to pointer indirection, so the compiler could
attempt to add an automatic "foo(in T bar)" overload if not
existent. For rvalues, the latter overload (i.e., "in T"
parameters) should be preferred over "in ref T" parameters -
exactly as the thread starter Malte proposes:
- Make functions that take "ref in" arguments also accept
rvalues.
- The user can still provide an overload that accepts an
rvalue, using the "in" keyword, and that one will be preferred
over the "ref in" version.