August 22, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2305

           Summary: ".sort" on array of struct can use templated "opCmp"
           Product: D
           Version: unspecified
          Platform: PC
               URL: http://codepad.org/63qU9Ndr
        OS/Version: Windows
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: tsalm@free.fr


Actually, to sort an array of "struct", ".sort" don't use a templated opCmp method.

Here is an example that illustrate the problem (same as in the url) :

import tango.io.Stdout;

struct A{
 int i;
 static A opCall(int j){ A a; a.i=j; return a; }
 int opCmp(T)(T b) { static if (is(T:A)||is(T:A*)) return (i-b.i); else return
false;}
}

struct B{ // opposite ordering
 int i;
 static B opCall(int j){ B res; res.i=j; return res; }
 int opCmp(T)(T b) { static if (is(T:B)||is(T:B*)) return -(i-b.i); else return
false; }
}

void main()
{
 int a=1,b=2;

 A a2=A(a),b2=A(b);
 Stdout("A")(a2.opCmp(b2))(" ")(a2<b2).newline;
 auto aa2=[a2,b2];

 B a3=B(a),b3=B(b);
 Stdout("B")(a3.opCmp(b3))(" ")(a3<b3).newline;
 auto aa3=[a3,b3];

 aa2.sort;
 aa3.sort;

 foreach(v;aa2) Stdout( v.i )(" ");
 Stdout.newline;
 foreach(v;aa3) Stdout( v.i )(" ");
 Stdout.newline;
}


-- 

August 22, 2008
<d-bugmail@puremagic.com> wrote in message news:bug-2305-3@http.d.puremagic.com/issues/...
> http://d.puremagic.com/issues/show_bug.cgi?id=2305
>
>           Summary: ".sort" on array of struct can use templated "opCmp"
>           Product: D
>           Version: unspecified
>          Platform: PC
>               URL: http://codepad.org/63qU9Ndr
>        OS/Version: Windows
>            Status: NEW
>          Severity: enhancement
>          Priority: P2
>         Component: DMD
>        AssignedTo: bugzilla@digitalmars.com
>        ReportedBy: tsalm@free.fr
>
>
> Actually, to sort an array of "struct", ".sort" don't use a templated
> opCmp
> method.
>
> Here is an example that illustrate the problem (same as in the url) :
>
> import tango.io.Stdout;
>
> struct A{
> int i;
> static A opCall(int j){ A a; a.i=j; return a; }
> int opCmp(T)(T b) { static if (is(T:A)||is(T:A*)) return (i-b.i); else
> return
> false;}
> }
>
> struct B{ // opposite ordering
> int i;
> static B opCall(int j){ B res; res.i=j; return res; }
> int opCmp(T)(T b) { static if (is(T:B)||is(T:B*)) return -(i-b.i); else
> return
> false; }
> }
>
> void main()
> {
> int a=1,b=2;
>
> A a2=A(a),b2=A(b);
> Stdout("A")(a2.opCmp(b2))(" ")(a2<b2).newline;
> auto aa2=[a2,b2];
>
> B a3=B(a),b3=B(b);
> Stdout("B")(a3.opCmp(b3))(" ")(a3<b3).newline;
> auto aa3=[a3,b3];
>
> aa2.sort;
> aa3.sort;
>
> foreach(v;aa2) Stdout( v.i )(" ");
> Stdout.newline;
> foreach(v;aa3) Stdout( v.i )(" ");
> Stdout.newline;
> }
>
>
> -- 
>

Unsurprising.  Templated functions/methods are not functions/methods until they are actually instantiated.  As far as D is concerned, you have not overloaded opCmp.

Also, you don't return "false" from opCmp.  If something can't be compared, you should give an error (in this case, you can use static assert to give a compile-time error).