Thread overview
Function overloads/implicit conversions
Jan 21, 2006
John C
Jan 21, 2006
John C
January 21, 2006
Should implicit conversions be allowed to occur with function overloads? I think not. At any rate, the behaviour seems inconsistent.

Case 1:

    void test(int a, Object b) {}
    void test(ulong a, Object b) {}

    test(100, null); // The compiler complains about mulitple matches.
    test(cast(int)100, null); // The compiler complains about mulitple
matches.

Case 2:

    void test(int a, Object b) {}
    void test(ulong a, Object b) {}

    test(100, new Object); // The compiler picks the right overload (int).

Case 3:

    void test(int a, Object b = null) {}
    void test(ulong a, Object b = null) {}

    test(100, null); // The compiler complains about mulitple matches.
    test(cast(int)100, null); // The compiler complains about mulitple
matches.

Case 4:

    void test(int a, Object b = null) {}
    void test(ulong a, Object b = null) {}

    test(100); // The compiler picks the right overload (int).

Case 5:

    void test(int a, Object b = null) {}
    void test(ulong a, Object b = null) {}

    test(100, new Object); // The compiler picks the right overload (int).


Can anyone explain why cases 1 & 3 fail to match?

Thanks.


January 21, 2006
Cast the null to an Object.  It has to match implicitly without other possibles, or exactly... iirc.

-[Unknown]


> Should implicit conversions be allowed to occur with function overloads? I think not. At any rate, the behaviour seems inconsistent.
> 
> Case 1:
> 
>     void test(int a, Object b) {}
>     void test(ulong a, Object b) {}
> 
>     test(100, null); // The compiler complains about mulitple matches.
>     test(cast(int)100, null); // The compiler complains about mulitple matches.
> 
> Case 2:
> 
>     void test(int a, Object b) {}
>     void test(ulong a, Object b) {}
> 
>     test(100, new Object); // The compiler picks the right overload (int).
> 
> Case 3:
> 
>     void test(int a, Object b = null) {}
>     void test(ulong a, Object b = null) {}
> 
>     test(100, null); // The compiler complains about mulitple matches.
>     test(cast(int)100, null); // The compiler complains about mulitple matches.
> 
> Case 4:
> 
>     void test(int a, Object b = null) {}
>     void test(ulong a, Object b = null) {}
> 
>     test(100); // The compiler picks the right overload (int).
> 
> Case 5:
> 
>     void test(int a, Object b = null) {}
>     void test(ulong a, Object b = null) {}
> 
>     test(100, new Object); // The compiler picks the right overload (int).
> 
> 
> Can anyone explain why cases 1 & 3 fail to match?
> 
> Thanks. 
> 
> 
January 21, 2006
"Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:dqu20f$1qno$1@digitaldaemon.com...
> Cast the null to an Object.  It has to match implicitly without other possibles, or exactly... iirc.

Right. Here's another.

    interface Base {}
    class Derived : Base {}

    void test(int a, Base b) {}
    void test(ulong a, Base b) {}

With this code the compiler thinks there's multiple matches:

    test(100, new Derived);

But it accepts this:

    test(100, cast(Base)(new Derived));

In what way was there any ambiguity with the first, cast-less form? And D's overloading claims to be simple. How depressing.

>
> -[Unknown]
>
>
>> Should implicit conversions be allowed to occur with function overloads? I think not. At any rate, the behaviour seems inconsistent.
>>
>> Case 1:
>>
>>     void test(int a, Object b) {}
>>     void test(ulong a, Object b) {}
>>
>>     test(100, null); // The compiler complains about mulitple matches.
>>     test(cast(int)100, null); // The compiler complains about mulitple
>> matches.
>>
>> Case 2:
>>
>>     void test(int a, Object b) {}
>>     void test(ulong a, Object b) {}
>>
>>     test(100, new Object); // The compiler picks the right overload
>> (int).
>>
>> Case 3:
>>
>>     void test(int a, Object b = null) {}
>>     void test(ulong a, Object b = null) {}
>>
>>     test(100, null); // The compiler complains about mulitple matches.
>>     test(cast(int)100, null); // The compiler complains about mulitple
>> matches.
>>
>> Case 4:
>>
>>     void test(int a, Object b = null) {}
>>     void test(ulong a, Object b = null) {}
>>
>>     test(100); // The compiler picks the right overload (int).
>>
>> Case 5:
>>
>>     void test(int a, Object b = null) {}
>>     void test(ulong a, Object b = null) {}
>>
>>     test(100, new Object); // The compiler picks the right overload
>> (int).
>>
>>
>> Can anyone explain why cases 1 & 3 fail to match?
>>
>> Thanks.


January 22, 2006
It's not simple in that it's easy to get around.  It's simple in that it isn't complicated (the dictionary definition.)

It matches exactly, it matches only once ambiguously, or not at all.

It may be annoying, but I like it.  Why?  Because I will NEVER have to worry about the wrong thing happening.  If I ever add a new function or make a change that is ambiguous, I will know.  It won't silently cause problems.

-[Unknown]


> "Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:dqu20f$1qno$1@digitaldaemon.com...
>> Cast the null to an Object.  It has to match implicitly without other possibles, or exactly... iirc.
> 
> Right. Here's another.
> 
>     interface Base {}
>     class Derived : Base {}
> 
>     void test(int a, Base b) {}
>     void test(ulong a, Base b) {}
> 
> With this code the compiler thinks there's multiple matches:
> 
>     test(100, new Derived);
> 
> But it accepts this:
> 
>     test(100, cast(Base)(new Derived));
> 
> In what way was there any ambiguity with the first, cast-less form? And D's overloading claims to be simple. How depressing.
> 
>> -[Unknown]
>>
>>
>>> Should implicit conversions be allowed to occur with function overloads? I think not. At any rate, the behaviour seems inconsistent.
>>>
>>> Case 1:
>>>
>>>     void test(int a, Object b) {}
>>>     void test(ulong a, Object b) {}
>>>
>>>     test(100, null); // The compiler complains about mulitple matches.
>>>     test(cast(int)100, null); // The compiler complains about mulitple matches.
>>>
>>> Case 2:
>>>
>>>     void test(int a, Object b) {}
>>>     void test(ulong a, Object b) {}
>>>
>>>     test(100, new Object); // The compiler picks the right overload (int).
>>>
>>> Case 3:
>>>
>>>     void test(int a, Object b = null) {}
>>>     void test(ulong a, Object b = null) {}
>>>
>>>     test(100, null); // The compiler complains about mulitple matches.
>>>     test(cast(int)100, null); // The compiler complains about mulitple matches.
>>>
>>> Case 4:
>>>
>>>     void test(int a, Object b = null) {}
>>>     void test(ulong a, Object b = null) {}
>>>
>>>     test(100); // The compiler picks the right overload (int).
>>>
>>> Case 5:
>>>
>>>     void test(int a, Object b = null) {}
>>>     void test(ulong a, Object b = null) {}
>>>
>>>     test(100, new Object); // The compiler picks the right overload (int).
>>>
>>>
>>> Can anyone explain why cases 1 & 3 fail to match?
>>>
>>> Thanks. 
> 
>