On Fri, Jul 25, 2014 at 02:05:13PM -0700, Walter Bright via Digitalmars-d wrote: > On 7/25/2014 12:03 PM, "Marc Schütz" <schue...@gmx.net>" wrote: > >No, if a type had only defined opCmp because of the previous AA > >(mis)implementation, > > It was not a misimplementation. The previous implementation used a > hash lookup with a binary tree for collisions, hence it needed cmp. It > was perfectly correct. The newer one uses a linear list for > collisions, hence it only needs ==.
So it sounds like Jonathan's solution is the best after all: get rid of the error message that demands that opEquals be defined when opCmp is defined. Previous code that defined opCmp for AA keys will then continue to work (except if their opCmp was inconsistent with the default opEquals, in which case they are already buggy and we're not making things worse). On a related note, it would be nice if AA key types that did define opCmp can have better than linear collision resolution. But that belongs in another discussion. On another related note, the compiler's treatment of opCmp is inconsistent: struct S { int opCmp(S s) { return 0; } } int[S] aa1; // OK struct T { int opCmp(T s) const { return 0; } } int[T] aa2; // Compile error: must also define opEquals Worse yet: struct S { int x; int opCmp(S s) /*const*/ { return s.x - x; } } void main() { auto s1 = S(1); auto s2 = S(2); assert(s1 > s2); assert(s2 < s1); assert(typeid(s1).compare(&s1, &s2) > 0); assert(typeid(s2).compare(&s2, &s1) < 0); } This produces a runtime error: object.Error@(0): TypeInfo.compare is not implemented Uncommenting the const in opCmp fixes the problem. WAT? T -- Без труда не выловишь и рыбку из пруда.