rvalues -> ref (yup... again!)

Manu turkeyman at gmail.com
Wed Mar 28 18:20:42 UTC 2018


On 28 March 2018 at 05:22, Timon Gehr via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On 27.03.2018 20:14, Manu wrote:
>>
>> That's exactly what I've been saying. For like, 9 years..
>> It looks like this:
>>
>> https://github.com/TurkeyMan/DIPs/blob/ref_args/DIPs/DIP1xxx-rval_to_ref.md
>>   (contribution appreciated)
>
>
> "Temporary destruction
> Destruction of any temporaries occurs naturally at the end of the scope, as
> usual."
>
> This is actually unusual.
>
> ---
> import std.stdio;
> struct S{
>     ~this(){
>         writeln("destroyed!");
>     }
> }
>
> void foo(S s){}
>
> void main(){
>     foo(S());
>     writeln("end the scope");
> }
> ---
>
> prints:
>
> destroyed!
> end the scope

Right, exactly...
So, what's wrong?


> "Overload resolution
> ...
> This follows existing language rules. No change is proposed here."
>
> Yes, you _are_ proposing a change. Right now rvalues "prefer" the by-value
> overload because the ref overload _does not match at all_. Now you make it
> match both, so you are adding additional disambiguation rules. You need to
> be more explicit about those.

Oh right... yeah okay, I'll tweak the language.


> Note that lvalues prefer the ref overload because the ref overload is more
> specialized. The new rule is the only instance where a less specialized
> overload is preferred.

I've never heard any discussion involving the term 'specialised', or
seen any definition where overloading prefers a "more specialised'
version... is that a thing?
Given:
  void f(int);
  void f(const(int));
  f(10);

That calls the 'int' one, but it could call either one... that's
definitely not choosing a 'more specialised' match.


> You also need to specify the interactions with matching levels
> (https://dlang.org/spec/function.html#function-overloading):
>
> E.g., your DIP is compatible with the following behavior:
>
> ---
> import std.stdio;
>
> struct S{}
> void fun(S){ writeln("A"); }
> void fun(ref const(S)){ writeln("B"); }
>
> void main(){
>     fun(S()); // calls A
>     S s;
>     fun(s); // calls A
>
>     const(S) t;
>     fun(t); // calls B
>     fun(const(S)()); // calls B
> }
> ---
>
> The first example will cause friction when people try to add an explicit
> rvalue overload alongside a previous catch-it-all overload, the second
> example shows a breaking language change.
>
> You cannot "fix" the first example without introducing breaking language
> changes. The above code compiles and runs in current D.
>
> This just smells bad. Remove the "const" requirement.

This is very compelling reason to remove the const.


More information about the Digitalmars-d mailing list