Jonathan M Davis wrote:
> On Sunday, August 26, 2012 14:47:38 Jens Mueller wrote:
> > What is the ref situation?
> > I thought ref is used as an optimization that allows passing lvalues
> > more efficiently whereas without ref is needed for rvalues.
>
> ref doesn't necessarily have anything to do with optimizations. It makes it
> so
> that any operations done on the function parameter inside the function are
> also done on the variable passed in. The parameter is essentially an alias
> for
> the variable passed in.
>
> You can choose to use ref in order to avoid a copy, but it's also arguably
> bad
> practice to have a function take an argument by ref if it's not actually
> going
> to mutate the original, since that's confusing.
>
> _const_ ref is more for avoiding the copy, since it's like ref except that
> you
> can't actually mutate the variable. So, it makes sense to use const ref
> specifically to avoid unnecessary copies.
This is what I meant.
> However, while in C++, you can pass rvalues to const&, in D, you can't. It
> doesn't matter if the ref is const or not, it still requires an lvalue. This
> solves certain issues caused by C++'s choice (issues primarily related to
> function overloading IIRC), but it makes it rather difficult to declare a
> single
> function which takes either an lvalue or an rvalue but which tries to avoid
> unnecessary copying.
>
> D's auto ref essentially does it (rvalues are then always passed by rvalue
> and
> lvalues are always passed by lvalue), but it only works with templates,
> because it has to create two versions of the function.
>
> So, what we'd _like_ to have is a solution where you can mark a parameter in
> a
> way similar to auto ref or C++s const& and have the function not care whether
> it's passed an lvalue or rvalue and have it avoid copying as much as possible
> and have it work with _all_ function types, not just templated ones, but we
> haven't sorted out how to do that yet. _That's_ the ref situation that needs
> to be solved.
Aha. I see.
Then we get down from four declarations to two by writing
bool opEquals(const auto ref S rhs) const {...}
and
bool opEquals(auto ref S rhs) {...}
And with inout probably even further:
bool opEquals(inout auto ref S rhs) inout {...}
Thanks for explaining.
Jens