www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Explicit call of ternary compare

reply "monarch_dodra" <monarchdodra gmail.com> writes:
Is there any (efficient and correct) way to do ternary comparison 
on two objects?

You know the:
----
if(a<b) return -1;
if(b<a) return 1;
return 0;
----

I'm using the above method in a template, and the problem is that 
if a or b is a struct/class, this will resolve to 4 (!) calls to 
opCmp.
Jul 23 2012
parent reply "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Mon, 23 Jul 2012 16:32:15 +0200, monarch_dodra <monarchdodra gmail.com>  
wrote:

 Is there any (efficient and correct) way to do ternary comparison on two  
 objects?

 You know the:
 ----
 if(a<b) return -1;
 if(b<a) return 1;
 return 0;
 ----

 I'm using the above method in a template, and the problem is that if a  
 or b is a struct/class, this will resolve to 4 (!) calls to opCmp.
First, no. It will only call opCmp twice - once for each comparison. You're thinking of opEquals. Second, have you tried a.opCmp(b), cause that's the logical thing to try, and it works. Like other operator magic in D, it's not really magic. It's just a simple lowering of a < b to a.opCmp(b) < 0. In other words, operator overload functions in D can be called just like regular functions: auto o = a.opOpAssign!"it's the 'look ma' operator!"("a string", 42, !false); // Don't expect this to work unless you've explicitly designed it to. -- Simen
Jul 23 2012
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 23 July 2012 at 15:37:17 UTC, Simen Kjaeraas wrote:
 On Mon, 23 Jul 2012 16:32:15 +0200, monarch_dodra 
 <monarchdodra gmail.com> wrote:

 Is there any (efficient and correct) way to do ternary 
 comparison on two objects?

 You know the:
 ----
 if(a<b) return -1;
 if(b<a) return 1;
 return 0;
 ----

 I'm using the above method in a template, and the problem is 
 that if a or b is a struct/class, this will resolve to 4 (!) 
 calls to opCmp.
First, no. It will only call opCmp twice - once for each comparison. You're thinking of opEquals.
Hum. Fine. I though that if a and b were class, then there was the same behavior. My bad. But that's still twice too many calls.
 Second, have you tried a.opCmp(b), cause that's the logical 
 thing to try, and it works.
It works but *if* the types are not equal, then this may or may not be equivalent to b.opCmp(a).
 Like other operator magic in D, it's not really magic. It's 
 just a simple lowering of a < b to a.opCmp(b) < 0.
 In other words, operator overload functions in D can be called 
 just like regular functions:
This lowering only applies: *If a.opCmp(b) and b.opCmp(a) resolve to the same function. *Otherwise, exactly one of a.opCmp(b) and b.opCmp(a) must be compilable. I'd agree with a rewrite, but there are tricky edge cases. I would have thought the language provided a ternary compare. If it doesn't, I'd say it should. Preferably in std.functional?
Jul 23 2012