[phobos] Issue with opEquals(Object, Object)

Steve Schveighoffer schveiguy at yahoo.com
Tue Apr 27 04:55:17 PDT 2010


I read the excerpt.

I understand the current implementation just fine.  The issue I have is with the line:

return lhs.opEquals(rhs) && rhs.opEquals(lhs);

I thought maybe || would be a better idea, but after reading the text, I agree the example shows that is not the best method.

Following the example in the book, let's say I make my own widget, called StevesTextWidget, which inherits Widget, not TextWidget.  It has some of the same functionality as TextWidget, but it's not a TextWidget.  If I want to be able to compare StevesTextWidget to a TextWidget, it's not possible, because the TextWidget will veto every time, even though StevesTextWidget has total understanding of TextWidget and can correctly do the comparison.  On the other hand, if || was used, comparing StevesTextWidget to a Widget will allow Widget's routine to override the opEquals of StevesTextWidget, and like the example in the book, could possibly cause an invalid equal response.

If Widget's routine is rewritten to return false when the actual derived class is not widget, then that forces derivative classes to always implement opEquals, even if it just calls the base method (which it can't because it will return false!).

We all agree that opEquals is a double-dispatch problem, but the "fix" being introduced causes 1) unreasonable performance problems and 2) unreasonable paranoia in some cases, to the point where opEquals will not be a universal way to determine equality.  You are making a decision both on equality and ability to determine equality with one bit.

Maybe the answer is to give more information than one bit.  This was my original idea, and I guess I'm back to that.  Like it or not, opEquals is a complex problem to solve, and taking a simple approach to it results in it's usefulness being extremely limited.  To be able to just use == when you want equality is a good goal to have, even if it means the opEquals regime is slightly more complex.

What I'm looking for is a way to give more information to the opEquals global function if you want to, but falls back to some reasonable default (such as the current behavior), if you don't care about performance or dealing with the complexity of the problem.  In other words, you don't *have* to override/define the canCompare function, the default simply always returns the same thing, and if you don't, you get the current behavior.  But if you want to optimize opEquals for specific cases (or make specific cases possible), you can override canCompare.

-Steve


      


More information about the phobos mailing list