digitalmars.D.bugs - Array .sort property doesn't play nicely with overloaded opCmp
- Jarrett Billingsley (40/40) Jul 15 2005 Look at the following code:
- John Demme (17/71) Jul 15 2005 I complained about this awhile ago. The problem is actually much more
- Brad Beveridge (5/81) Jul 15 2005 Though I can see why this was once a problem, now that D has templates
Look at the following code: import std.stdio; import std.random; class A { this(int a) { x=a; } int x; int opCmp(A other) { return x-other.x; } } void main() { A[] a=new A[10]; foreach(uint i, inout A ai; a) { ai=new A(rand() % 10); writefln(ai.x); } a.sort; writefln(); foreach(A ai; a) { writefln(ai.x); } } The problem is that a[] is not sorted. But change the opCmp() to this: int opCmp(Object o) { A other=cast(A)o; return x-other.x; } And it works fine. The array .sort property is only looking for opCmp(Object) overloads; it doesn't like any other parameter type. This is inconsistent with the behavior of the comparison operators, which do use the overloaded opCmps.
Jul 15 2005
I complained about this awhile ago. The problem is actually much more generic than with arrays. Any class A which overloads Object's opCmp, and uses a more specific parameter, say a class A (this class is your class A) doesn't actually overload it. That is, if you're looking at A as an object, not an A, it'll never call A.opCmp. The reason this affects arrays, is because all class arrays are effectively cast into Objects- you'd have to look into the array sources in Phobos to determine exactly why this is. I see this as a big issue, but not one that's too hard to get around. Add the follow to A: int opCmp(Object o) { A a = cast(A)o; if (a !is null) return opCmp(a); assert(false); } On Fri, 2005-07-15 at 14:30 -0400, Jarrett Billingsley wrote:Look at the following code: import std.stdio; import std.random; class A { this(int a) { x=a; } int x; int opCmp(A other) { return x-other.x; } } void main() { A[] a=new A[10]; foreach(uint i, inout A ai; a) { ai=new A(rand() % 10); writefln(ai.x); } a.sort; writefln(); foreach(A ai; a) { writefln(ai.x); } } The problem is that a[] is not sorted. But change the opCmp() to this: int opCmp(Object o) { A other=cast(A)o; return x-other.x; } And it works fine. The array .sort property is only looking for opCmp(Object) overloads; it doesn't like any other parameter type. This is inconsistent with the behavior of the comparison operators, which do use the overloaded opCmps.
Jul 15 2005
John Demme wrote:I complained about this awhile ago. The problem is actually much more generic than with arrays. Any class A which overloads Object's opCmp, and uses a more specific parameter, say a class A (this class is your class A) doesn't actually overload it. That is, if you're looking at A as an object, not an A, it'll never call A.opCmp. The reason this affects arrays, is because all class arrays are effectively cast into Objects- you'd have to look into the array sources in Phobos to determine exactly why this is. I see this as a big issue, but not one that's too hard to get around. Add the follow to A: int opCmp(Object o) { A a = cast(A)o; if (a !is null) return opCmp(a); assert(false); } On Fri, 2005-07-15 at 14:30 -0400, Jarrett Billingsley wrote:Though I can see why this was once a problem, now that D has templates can't this be corrected internally to use correctly typed arrays inside Phobos? BradLook at the following code: import std.stdio; import std.random; class A { this(int a) { x=a; } int x; int opCmp(A other) { return x-other.x; } } void main() { A[] a=new A[10]; foreach(uint i, inout A ai; a) { ai=new A(rand() % 10); writefln(ai.x); } a.sort; writefln(); foreach(A ai; a) { writefln(ai.x); } } The problem is that a[] is not sorted. But change the opCmp() to this: int opCmp(Object o) { A other=cast(A)o; return x-other.x; } And it works fine. The array .sort property is only looking for opCmp(Object) overloads; it doesn't like any other parameter type. This is inconsistent with the behavior of the comparison operators, which do use the overloaded opCmps.
Jul 15 2005