opAssign overload question

bearophile bearophileHUGS at lycos.com
Thu Apr 25 12:22:30 PDT 2013


Ali Çehreli:

> The type of literal 1 is int, not long. So, both functions are 
> matched with implicit conversions. According to "Function 
> Overloading" here:
>
>   http://dlang.org/function.html
>
> The match is later resolved by "If two or more functions have 
> the same match level, then partial ordering is used to try to 
> find the best match. Partial ordering finds the most 
> specialized function."
>
> If bool is considered to be more specialized than long, then 
> the compiler is behaving according to spec. It is very 
> confusing indeed. Especially, considering that an int 
> *variable* would be matched to long:
>
>     auto i = 1;
>     foo(i);
>
> Now the long overload gets called!

This is the code of the OP improved a little:


import std.stdio;

struct Value {
     public enum Type { bool_, long_ }

     private long longVal;
     private bool boolVal;
     private Type type;

     Value opAssign(in long val) pure nothrow {
         longVal = val;
         boolVal = val != 0;

         type = Type.long_;
         return this;
     }

     Value opAssign(in bool val) pure nothrow {
         longVal = val;
         boolVal = val;

         type = Type.bool_;
         return this;
     }

     Type getType() {
         return type;
     }

}

void main() {
     Value data;

     data = 1;
     data.writeln;
     data.getType.writeln;
     assert(data.getType == Value.Type.bool_);

     writeln;

     data = 10;
     data.writeln;
     data.getType.writeln;
     assert(data.getType == Value.Type.long_);
}


Indeed, such implicit casting rules and overload rules are quite 
arbitrary, and they cause confusion. Functional languages try 
hard to not have them.

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list