implicit cast and overload priority

Dom DiSc dominikus at scherkl.de
Fri Feb 14 04:28:25 UTC 2025


Why does this happen:

```d
void foo(long x) { }
void foo(ulong x) { }

main()
{
    foo(short(17)); // error: `foo` called with argument types 
`(short)` matches both: `foo(long x)` and: foo(ulong x)`
}
```

Why does a short match an unsigned type with same priority as a 
signed type?!?
Clearly a longer type with matching signedness should always be a 
better match than a type that will discard the sign, no?

Because of this bug I often have to make weird workarounds like:

```d
void foo(ulong x)
{
    ...
}

void foo(T)(T y) if(isIntegral!T && isSigned!T)
{
    long x = y;
    ...
}
```

or vice versa.

And another problem with overloads is, that only in the current 
module is searched for matches, even if functions with same name 
are imported explicitly:

```d
module A;
void foo(int x) { ... }

module B;
import A : foo;

void foo(T)(T x) if(!is(Unqual!T==int))
{
    ...
}

main()
{
    foo(-3); // error: template `foo` is not callable using 
argument types `!()(int)` Candidate is: `foo(T)(T x)` with `T = 
int`
   must satisfy the following constraint: `!is(Unqual!T == int)`
}
```

A workaround in B is:


```d
void foo(T)(T x)
{
    static if(is(Unqual!T==int) return A.foo(x); // here 
explicitly a fully qualified name is required, else the compiler 
doesn't find it
    ...
}
```

But this cannot be in A, because then again the error "matching 
both" occurs.


More information about the Digitalmars-d-learn mailing list