On 7/23/14, 1:45 PM, H. S. Teoh via Digitalmars-d wrote:
This morning, I discovered this major WAT in D:---- struct S { int x; int y; int opCmp(S s) { return x - s.x; // compare only x } } void main() { auto s1 = S(1,2); auto s2 = S(1,3); auto s3 = S(2,1); assert(s1 < s3); // OK assert(s2 < s3); // OK assert(s3 > s1); // OK assert(s3 > s2); // OK assert(s1 <= s2 && s2 >= s1); // OK assert(s1 == s2); // FAIL -- WAT?? } ---- The reason for this is that the <, <=, >=, > operators are defined in terms of opCmp (which, btw, is defined to return 0 when the objects being compared are equal), but == is defined in terms of opEquals. When opEquals is not defined, it defaults to the built-in compiler definition, which is a membership equality test, even if opCmp *is* defined, and returns 0 when the objects are equal. Why isn't "a==b" rewritten as "a.opCmp(b)==0"?? I'm pretty sure TDPL says this is the case (unfortunately I'm at work so I can't check my copy of TDPL). https://issues.dlang.org/show_bug.cgi?id=13179 :-( T
Imagine you have a list of integers and strings denoting integers: [1, "2", 100, "38"]. Now you want to sort them according to their numeric value. Of course, 1 and "1" would have the same order. However, 1 and "1" are different, so "==" would give false, while 1.opCmp("1") would give 0.
Equality and comparison are different. opCmp is used for sorting objects, which has nothing to do with equality. Inferring equality from opCmp is wrong in my opinion.
