How to implement opCmp?

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jun 9 08:12:42 PDT 2017


On 6/9/17 10:53 AM, Honey wrote:
> Hi everyone!
>
> Given
>
> struct Pair(T, U = T)
> {
>   T f;
>   U s;
> }
>
> what is the intended way to genrically implement opCmp for this struct?
>
> The naive approach
>
> struct Pair(T, U = T)
> {
>   // [...]
>
>   int opCmp(const Pair r) const
>   {
>     immutable c = f.opCmp(r.f);
>     return c != 0 ? c : s.opCmp(r.s);
>   }
> }
>
> yields
>
> Error: no property 'opCmp' for type 'const(int)'
>
> if one tries to compare pairs of int.

TypeInfo can provide the comparison for you, but it's a little ugly.

If we take a look at std.algorithm.comparison.cmp, it uses operators to 
compare two values (i.e. < first, then >, otherwise return 0). However, 
this is less performant if the type defines opCmp (you are calling it 
twice).

There really ought to be an opCmp for any type, which does the best 
thing available. I'm not sure if it exists.

If I were to write it, it would be something like:

int doCmp(T)(auto ref T t1, auto ref T t2)
{
    static if(is(typeof(t1.opCmp(t2))))
	return t1.opCmp(t2);
    else
    {
       if(t1 < t2) return -1;
       else if(t1 > t2) return 1;
       return 0;
    }
}

Then your function would work, just use doCmp instead of opCmp.

Note that D already (I think) does by default a member-wise comparison, 
in order of declaration. So if that's all you really need, I don't think 
you need to define opCmp at all.

-Steve


More information about the Digitalmars-d-learn mailing list