On Thursday, 20 June 2019 at 00:30:35 UTC, Jonathan M Davis wrote:
Ultimately, if you want a function to accept both rvalues and
lvalues as efficiently as posible, just templatize it and use
auto ref.
I'm aware of auto ref, and I've used it to solve this same
problem when I had a template, but as you say it works with
templates only, not plain non-templated functions.
Or another possible optimization: in case the function is
declared with const parameters (not ref), lvalues can be
accessed by ref as an optimization; and rvalues can use the
same trick they do now. As a consequence, no unnecessary
copies ever -- thanks to const. This is even better because I
don't have to type so many ref, which were never part of the
algorithm but baby instructions for the dumb compiler (const &
everywhere is one of the ugliest and most annoying things in
C++).
Either way, const has nothing to do with any of this. You're
free to mark a ref or auto ref parameter as const, but it has
nothing to do with whether rvalues are accepted, and it will
never have anything to do with whether rvalues are accepted.
D's const is far too restrictive for it to make any sense to
base rvalue stuff on it like they do in C++. The DIP has
nothing do with const and everything to do with ref.
[...]
Regardless, the refness of a parameter is part of its type, and
I'd be very surprised if it were ever changed so that any
parameter that was not marked with ref was ever ref.
I know. That's why I look to the general solution to bind ref
rvalues as a solution to bind const ref in particular. By the way
it looks to me that most of the demand in the D community to bind
to ref is for chain return ref functions. I wonder why no one in
D is bothered about not being able to use const ref parameters
easily, while in C++ everyone is bothered to do it, and passing a
read-only struct/class by value won't pass by the least alert
reviewer. My guess is that in D it's very often ranges that get
passed, and these are passed as slices, which are by nature refs
that don't reallocate, and can also be decorated const. Still the
const ref concern stays more or less. Rust has a solution too (&)
of course.
My new idea about const only would be a compiler optimization,
not part of the language/ABI. The same way as RVO, which under
the hood (but not at the ABI level) is implemented as changing
the function signature completely. This const optimization would
not change the function's ABI either.
However I see a practical problem to implement this optimization
idea. RVO changes the function signature under the hood, but in
the same way for every occurrence/call. This const optimization
would need to change the signature, but only in the occurrences
where the function is called with lvalues instead,not rvalues. So
in practice turning every function with const struct parameters
as a template; but under the hood, maintaining a single plan
signature in the ABI. I wonder if this is as easy or feasible as
RVO.