On Monday, July 08, 2013 16:38:16 H. S. Teoh wrote: > On Tue, Jul 09, 2013 at 12:35:32AM +0200, Ugbar Ikenaki wrote: > > Here's one more question: > > > > Before I knew that opEquals existed, I tried overloading the > > equality expressions (== and !=) in opBinary using the code below. > > It worked. Why would the overloaded opBinary version get called if > > the equality expressions are held in opEquals? > > [...] > > I doubt opBinary was actually called. Probably what happened was that == > defaulted to the built-in implementation of opEquals, which simply > performs a bitwise comparison of the struct/class, and it just so > happened that it was close to (or the same) as what you intended. > > Basically, when you write x==y, the compiler looks for opEquals and > opCmp. If opEquals is found, then it's rewritten as x.opEquals(y); > otherwise, if opCmp is found, it's rewritten as x.opCmp(y)==0. If > neither are found, then the compiler generates a default implementation > of opEquals, which basically does a bitwise comparison of x and y.
Actually, what it's supposed to do isn't necessarily a bitwise comparison. It's supposed to do a recursive comparison of all of the members, where it calls == on each of the members. If a bitwise comparison will do that, then it may end up as a bitwise comparison for efficiency reasons, but it's not necessarily a bitwise comparison. It used to be that it was doing a bitwise comparison when it wasn't supposed to, but that was fixed fairly recently (though I don't recall if that fix has been released yet). Basically, there's no reason to overload opEquals unless you have a member which you don't want to compare with == (e.g. pointers). - Jonathan M Davis