On Thursday, 8 November 2012 at 03:07:00 UTC, Jonathan M Davis wrote:
Okay. Here are more links to Andrei discussing the problem:

http://forum.dlang.org/post/[email protected]
http://www.mail-archive.com/[email protected]/msg44070.html
http://www.mail-archive.com/[email protected]/msg43769.html
http://forum.dlang.org/post/[email protected]

Thank you so much for these links, Jonathan.

So fortunately the special role of _const_ ref parameters has been acknowledged.

From the 2nd  link:
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.

This is exactly what we propose (to be able to avoid pointer/reference indirection for rvalues in some absolutely performance-critical cases). Unlike Andrei though, I don't find the required overloading rules complicated at all, quite the contrary in fact.

From the 3rd link:
Binding rvalues to const references was probably the single
most hurtful design decisions for C++. I don't have time to
explain now, but in short I think all of the problems that
were addressed by rvalue references, and most of the
aggravation within the design of rvalue references, are owed
by that one particular conversion.

Here's where I totally disagree with Andrei. C++ rvalue references (T&&) aren't used to distinguish between lvalues and rvalues when expecting a _const_ reference (I still have to see a use case for 'const T&&'). They are used for _mutable_ references and primarily to enforce efficient move semantics in C++, i.e., to move _mutable_ rvalue arguments (instead of copying them) and to enforce 'Named Return Value Optimization' when returning lvalues (by using std::move; goal again is to avoid a redundant copy). D fortunately seems to implement move semantics out-of-the-box (at least now in v2.060), in both cases, see Rob T's posts and my replies in this thread. Besides implementing move semantics, C++ with its rvalue refs also implicitly provides a way to distinguish between _mutable_ lvalue and rvalue references and so allows optimized implementations - that is something we'd also need in D, but that's what we've just covered with regard to the 2nd link.

So I still don't see a valid reason to preclude binding rvalues to const ref parameters.

Reply via email to