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