opCmp, opEquals

Ary Borenszweig ary at esperanto.org.ar
Thu Oct 23 11:42:25 PDT 2008


bearophile wrote:
> Steven Schveighoffer:
>> Given that the default implementation just compares references, I think C1 
>> is correct.
>> Otherwise you have weird shit like this:
>> [...something bad]
> 
> In that C1 class I have left out the implementation of opCmp, let's say I use the following one (C4a and C4b have the same code, but they are distinct classes):
> 
> class UncomparableException: Exception {
>     this() {
>         super(this.classinfo.name);
>     }
>     this(string msg) {
>         super(this.classinfo.name ~ ": " ~ msg);
>     }
> }
> 
> 
> class C4a { // Like Java?
>     int x;
>     this(int x) { this.x = x; }
> 
>     int opEquals(Object o) {
>         if (this is o)
>             return 1;
>         auto oc = cast(typeof(this))o;
>         if (oc is null)
>             return 0;
>         else
>             return this.x == oc.x;
>     }
> 
>     int opCmp(Object o) {
>         if (this is o)
>             return 0;
>         auto oc = cast(typeof(this))o;
>         if (oc is null)
>             throw new UncomparableException();
>         else
>             return this.x - oc.x;
>     }
> }
> 
> 
> class C4b { // Like Java?
>     int x;
>     this(int x) { this.x = x; }
> 
>     int opEquals(Object o) {
>         if (this is o)
>             return 1;
>         auto oc = cast(typeof(this))o;
>         if (oc is null)
>             return 0;
>         else
>             return this.x == oc.x;
>     }
> 
>     int opCmp(Object o) {
>         if (this is o)
>             return 0;
>         auto oc = cast(typeof(this))o;
>         if (oc is null)
>             throw new UncomparableException();
>         else
>             return this.x - oc.x;
>     }
> }
> 
> void main() {
>     auto x = new C4a(1);
>     auto y = new C4b(2);
> 
>     printf(x == y ? "x == y\n" : "x != y\n"); // else
>     printf(x.opCmp(y) == 0 ? "x ==2 y\n" : "x !=2 y\n"); // throws
> }
> 
> I think that's more bad behavior.
> But then what can I do? remove the UncomparableException from opCmp too, and make it return randomly -1 or +1 when the classes can't be cast, like this?

If you are comparing something to something else that you shouldn't be 
comparing, an exception is the best solution. It will fail fast, and 
show you that there is an error in your application code.

Another altenative, more in the D style, it to place an assert:

int opCmp(Object o) {
      if (this is o)
          return 0;

      assert(typeof(o) is typeof(this));

      auto oc = cast(typeof(this))o;
      return this.x - oc.x;
}


More information about the Digitalmars-d-learn mailing list