Steven Schveighoffer <schvei...@yahoo.com> wrote:

Nope.  try it:

interface I { bool opEquals(I other); }

I a;
I b;

a == b; // same error.

The problem is that when TDPL was implemented, (Object)a == (Object)b was redefined from a.opEquals(b) to object.opEquals(a, b), where object is the module object.

That function's signature looks like this:

bool opEquals(Object lhs, Object rhs);

For some reason the compiler tries to do the same thing with interfaces, but of course, there is no opEquals for your specific interface in object. Even if there was, you'd likely get an overload error.

This would be easily resolved if interfaces were known to be Objects.

There's another way that should work, replacing the global opEquals in
object.di with this:


equals_t opEquals(T, U)(T lhs, U rhs)
if ((is(T == class) || is(T == interface)) && (is(U == class) || is(U == interface)))
{
    if (lhs is rhs)
        return true;
    if (lhs is null || rhs is null)
        return false;
    static if (__traits(compiles,{lhs.opEquals(rhs);}))
    {
        if (typeid(lhs) == typeid(rhs))
            return lhs.opEquals(rhs);
static if (__traits(compiles,{lhs.opEquals(rhs) && rhs.opEquals(lhs);}))
        {
            return lhs.opEquals(rhs) &&
                rhs.opEquals(lhs);
        }
else static assert( false, T.stringof ~ " cannot be compared to a " ~ U.stringof );
    }
else static assert( false, T.stringof ~ " cannot be compared to a " ~ U.stringof );
}


There are some problems, however. This generates bloat, as instantiations
are created for each combination of types compared. Also, it is only tested
for a few simple cases.

--
Simen

Reply via email to