endless loop with ref and non-ref parameter

Era Scarecrow rtcvb32 at yahoo.com
Thu Jan 24 12:25:50 PST 2013


On Thursday, 24 January 2013 at 20:06:34 UTC, Ali Çehreli wrote:
> On 01/24/2013 11:33 AM, Jonathan M Davis wrote:
>
>> It's intended. constness matters more than refness when 
>> selecting a function overload. From the docs ( 
>> http://dlang.org/function.html#<u>function</u>-overloading ):
>>
>> -----
>> Functions are overloaded based on how well the arguments to a 
>> function can match up with the parameters. The function with 
>> the best match is selected. The levels of matching are:
> >
>> no match
>> match with implicit conversions
>> match with conversion to const
>> exact match
>> -----
>
> That doesn't explain why the first case selects the ref 
> function:
>
> void foo(A a) {
>     writeln("without ref");
>     foo(a);                    // <-- why is this foo(ref A)?
> }

  Because your local variable (in the signature) becomes a lvalue 
and thereby reference-able.

>
> void foo(ref A a) {
>     writeln("with ref");
> }
>
> foo(A) is the exact match there because the type of a is A.

> What is also considered in function selection is the 
> rvalue-lvalue distinction, which shouldn't affect the outcome 
> here either.

  In case David's explanation was too confusing, then let's look 
at it. If your variable is non-const, it will always select a 
non-const matching one first. If there is no matching non-const, 
it converts it to const, then tries again.

   void foo(A a) {
     writeln("without ref");
     //a is an lvalue but not const
     //Foo(A) matches closer. Infinite loop
     foo(a);
   }

   void foo(const ref A a) {
     writeln("with ref");
   }

   void foo2(A a) {
     writeln("foo2 - without ref");
     //const lvalue, foo(const ref A) is closer
     foo(cast(const A) a)

     //rvalue, postblit call foo(A) (if it can)
     foo(cast(const A) A());
   }


  I know this very issue seems like a big annoyance, to me too. 
I'd say the order of preference should be const ref, const 
non-ref, ref, non-ref. But then you can't have const & non const 
versions unless the signature differs, like ref, more input 
variables or the function itself is const.

  Until/unless that is changed all 4 versions need to be written 
(as David said) to make the proper calls.


More information about the Digitalmars-d-learn mailing list