opEquals the template?

kenji hara k.hara.pg at gmail.com
Fri Sep 30 23:32:48 PDT 2011


2011/10/1 Steven Schveighoffer <schveiguy at yahoo.com>:
> Yes, you did almost exactly what I did, except I made it valid to call
> mutable opEquals for two unlike objects.
>
> That is, I think there is no point for the static if in the middle, just do
> lhs.opEquals(rhs) && rhs.opEquals(lhs) for all cases.

Your suggestion makes object.opEquals more simple. It is good.

I worried that direct comparison partially breaks "Liskov substitution
principle", but D can detect "HiddenFuncError" in compile time, then
it is not so bug prone.
----
// comparing with any other types returns true
class X
{
    bool opEquals(const Object o) const { return true; }
}

// provide special opEquals against class X
class C
{
    bool opEquals(const Object o) const { return true; }
    bool opEquals(const X o) const { return true; }
}

// provide special opEquals against class X too, and rewrite its behavior
class D : C
{
    override bool opEquals(const Object o) const
    {
        if (auto x = cast(const X) o)
            return opEquals(x);
        return true;
    }
    override bool opEquals(const X o) const pure nothrow
    {
        return false;
    }

    // In class D, we should define two opEquals, otherwise raises
HiddenFuncError in compile time.
}

void main()
{
    auto x = new X();
    {
        auto c = new C();
        assert(c == x);

        auto oc = c, ox = x;
        assert(oc == ox);
    }
    {
        auto d = new D();
        assert(d != x);  // direct comparison

        C cd = d;
        assert(cd is d);
        assert(cd != x); // instance based behavior, it is consistent

        Object od = d, ox = x;
        assert(od != x); // opEquals(const Object) const is used, it
is required the right definition of opEquals in class D
    }
}
----

We still define the two opEquals properly (e.g. in class D), but I
think it is right cost to specialization.

Kenji Hara


More information about the Digitalmars-d mailing list