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