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

Timon Gehr timon.gehr at gmx.ch
Wed Mar 28 20:34:30 UTC 2018


On 28.03.2018 20:20, Manu wrote:
> 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.
>>  ...
> ...
> So, what's wrong?
> ...

In my example, the temporary is destroyed after/at the end of the 
function call, not at the end of the scope.

Re-reading the DIP, I think you meant the right thing, but the wording 
is a bit confusing. Maybe just clarify that "the scope" is the one your 
rewrite introduces implicitly, or explicitly state that the lifetime 
ends at the end of the function call.

> 
>> "Overload resolution
>> ...
> 
>> 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...

The overload resolution rules in D have four different matching levels:

- exact match
- match with type qualifier conversion
- match with general implicit conversion
- no match

The matching level for one overload is the minimal matching level for 
any argument. In your example f(int) matches exactly, but f(const(int)) 
matches with type qualifier conversion, therefore f(int) is chosen as it 
is the unique function that matches best.

Only if two overloads match with the same best level is specialization 
used. An overload A is more specialized than another overload B if we 
can call B with all arguments with which we can call A. As it is 
possible to call a by-value function with an lvalue or an rvalue, but 
ref cannot be called with an rvalue, ref is more specialized.

> that's definitely not choosing a 'more specialised' match.
> ...

Implicit conversions are ignored when checking for specialization so, 
yes, here both functions are equally specialized. However, f(int*) is 
more specialized than f(const(int)*):

---
import std.stdio;

void f(int* a){
     writeln("A");
}
void f(const(int)* b){
     writeln("B");
}

void main(){
     f(new immutable(int)); // guess what this prints. :)
}
---


More information about the Digitalmars-d mailing list