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