[Issue 9999] Integer literal 0 and 1 should prefer integer type in overload resolution
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Sun Feb 1 14:43:05 PST 2015
https://issues.dlang.org/show_bug.cgi?id=9999
--- Comment #14 from Jonathan M Davis <issues.dlang at jmdavisProg.com> ---
(In reply to Denis Shelomovskij from comment #12)
> Also this issue has to terrible consequences:
> 1. `f(bool)` is preferred over `f(T)(T)`
> 2. expressions like `4 - 3` triggers the issue too
>
>
> This code should run fine:
> ---
> int f1(bool) { return 1; }
> int f1(T)(T) { return 2; }
>
> void f2()(bool) { static assert(0); }
> void f2(T)(T) { }
>
> void main()
> {
> assert(f1( 0) == 2); // fails
> assert(f1( 1) == 2); // fails
> assert(f1( 1U) == 2); // fails
> assert(f1(4 - 3) == 2); // fails
>
> f2( 0); // triggers `static assert(0)`
> f2( 1); // ditto
> f2( 1U); // ditto
> f2(4 - 3); // ditto
> }
> ---
That seems pretty bad. It's things like that which make it so that I think that
it's usually a bad idea to overload templated and non-templated functions. It's
_far_ too easy to have the non-templated one called when you wanted the
templated one to be called.
> A workaround is to use `f(T : bool)(T)` specialization instead of `f(bool)`.
That's also probematic in general, because then stuff like user-defined types
which implicitly convert to bool could qualify, and frequently such functions
do not take that into account. It can certainly be made to work, and I think
that it's great that we can do it, but in general, I think that using implicit
conversions in template constraints and specializations is a mistake. If you
really want it to take bool though, you can just make the type exact with a
template constraint. e.g.
void f1(T)(T t)
if(is(T == bool))
{}
It's ugly that you would have to do that, but it should make it so that the
function will only work if it's actually give a bool, which is what you're
looking for.
Regardless, I think that it's a mistake for VRP to apply to bool. As far as I
can tell, it's never of any use, and it's error-prone. IMHO, the fact that
foo(1) would call a boolean overload instead of a long overload (which pretty
much no one expects) shows that the current behavior is a mistake. And your
example is far worse. I suspect that most of us would have run into exactly the
same problem and be very surprised by the current behavior.
--
More information about the Digitalmars-d-bugs
mailing list