On 12/10/10 12:46 PM, Steven Schveighoffer wrote:
On Mon, 06 Dec 2010 08:34:20 -0500, Steven Schveighoffer
<schvei...@yahoo.com> wrote:

On Sun, 05 Dec 2010 09:18:13 -0500, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:

On 12/5/10 12:04 AM, Steven Schveighoffer wrote:
I'm totally confused. I thought the point of auto ref was to pass by
value if it's an rvalue (since the data is already on the stack). If
this is not the case, then why not just make ref work that way? Why
wouldn't I mark all my functions as auto ref to avoid being pestered by
the compiler?

Because you sometimes do care about dealing with a true lvalue.
Consider:

void bump(ref int x) {
++x;
}

Then:

unsigned int y;
bump(y); // you don't want this to go through
short z;
bump(z); // you don't want this to go through
int w;
bump(w * 2); // you don't want this to go through

Right.

OK, so now I understand what you are saying, but now I don't
understand why const ref is such a mistake. Before you explained it
was because when you pass an rvalue by ref, it's much more expensive,
so auto ref passes by ref if it's an lvalue and by value if it's an
rvalue. At least that's what I understood.

With const ref, you get the same behavior, plus you are guaranteed
that the code isn't going to do something stupid (like modify a value
that will be thrown away at the end).

Not sure if this got lost in the noise, I'm still puzzled about this...

Sorry, indeed I haven't seen it.

The problem with binding rvalues to const ref is that once that is in place you have no way to distinguish an rvalue from a const ref on the callee site. If you do want to distinguish, you must rely on complicated conversion priorities. For example, consider:

void foo(ref const Widget);
void foo(Widget);

You'd sometimes want to do that because you want to exploit an rvalue by e.g. moving its state instead of copying it. However, if rvalues become convertible to ref const, then they are motivated to go either way. A rule could be put in place that gives priority to the second declaration. However, things quickly get complicated in the presence of other applicable rules, multiple parameters etc. Essentially it was impossible for C++ to go this way and that's how rvalue references were born.

For D I want to avoid all that aggravation and have a simple rule: rvalues don't bind to references to const. If you don't care, use auto ref. This is a simple rule that works promisingly well in various forwarding scenarios.


Andrei

Reply via email to