<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Mar 9, 2014 at 6:37 PM, Arthur O'Dwyer <span dir="ltr"><<a href="mailto:arthur.j.odwyer@gmail.com" target="_blank">arthur.j.odwyer@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="">On Sun, Mar 9, 2014 at 12:14 AM, Ahmed Charles <<a href="mailto:acharles@outlook.com">acharles@outlook.com</a>> wrote:<br>
> ________________________________<br>
>> Date: Fri, 7 Mar 2014 14:15:32 -0800<br>
>> Subject: Re: r203293 - [C++11] Revert uses of lambdas with array_pod_sort.<br>
>> From: <a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a><br>
>> To: <a href="mailto:arthur.j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a><br>
>> CC: <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
>><br>
</div><div class="">>> On Fri, Mar 7, 2014 at 2:10 PM, Arthur O'Dwyer <<a href="mailto:arthur.j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>> wrote:<br>
>><br>
>>> - The spaceship operator <=> is equivalent to (a < b) ? -1 : (a> b)<br>
>><br>
>> The more usual idiom of<br>
>><br>
>> if (!=)<br>
>> return <<br>
>><br>
>> naturally extends to lexicographical comparisons of multiple things. I<br>
>> don't see how to do that with (a<b?-1:a>b).<br>
<br>
</div>Recognizing that this is off-topic and also completely "personal<br>
style", I think your classification of (a != b) ? (a < b) ? -1 : +1 :<br>
0 as "more usual" is subjective.</blockquote><div><br></div><div>I don't think I've seen it written like that. I've seen this:</div><div><br></div><div>if (a.x != b.x) return a.x < b.x ? -1 : 1;</div>
<div>if (a.y != b.y) return a.y < b.y ? -1 : 1;</div><div>// ...</div><div>return 0;</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">In my subjective experience, (a < b)<br>
? -1 : (a > b) is "more usual". ;)<br>
<br>
If you have multiple fields in your struct, then (as Ahmed suggests)<br>
the most stylish idiom is to 'tie' your fields together.<br></blockquote><div><br></div><div>If you assume that your fields have < and == with roughly equal costs (and are complex enough that the two approaches won't get optimized to the same code), your 'tie' approach is 2-4x more expensive. If you have N fields, the ==/< approach uses at most N+1 comparisons. The 'tie' approach uses up to 2N comparisons for each < operation, and does either 1 or 2 of those.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
template<typename T> int spaceship(const T& a, const T& b) {<br>
return (a < b) ? -1 : (a > b); } // trivial<br>
<br>
struct S {<br>
int x, y, z;<br>
decltype(auto) toTuple() const { return std::tie(x,y,z); } //<br>
unfortunately annoying to type pre-C++14, but still trivial<br>
};<br>
<br>
bool operator< (const S& a, const S& b) { return a.toTuple() <<br>
b.toTuple(); } // trivial<br>
int spaceship(const S& a, const S& b) { return<br>
spaceship(a.toTuple(), b.toTuple()); } // trivial<br>
<br>
Unfortunately I don't think C++1y has added any special library<br>
support for the spaceship function, which means all the solutions<br>
named so far involve computing (a.x==b.x), (a.y==b.y), etc., up to the<br>
point of the first difference, TWICE. You can work around the lack of<br>
std::spaceship (or std::tuple::tail or whatever you choose as your<br>
missing primitive) and make the stylish solution also efficient, but I<br>
won't write it here because the guts are embarrassingly ugly. :P<br>
<span class="HOEnZb"><font color="#888888"><br>
–Arthur<br>
</font></span></blockquote></div><br></div></div>