opCmp, opEquals

Carl Clark carlclark at lavabit.com
Thu Oct 23 18:52:25 PDT 2008


On 2008-10-23 11:42, Ary Borenszweig wrote:
> 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;
> }
I don't think assert is quite what you'd want here; it seems like an 
exception is really better, since asserts are more for invariant 
conditions -- the function doesn't know that no one will ever call it 
with bad arguments, so it shouldn't be an assert.


More information about the Digitalmars-d-learn mailing list