opCmp, opEquals

bearophile bearophileHUGS at lycos.com
Thu Oct 23 11:31:32 PDT 2008


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?


class C5 { // ?
    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)
            return 1; // random value != 0
        else
            return this.x - oc.x;
    }
}

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list