r203293 - [C++11] Revert uses of lambdas with array_pod_sort.

David Blaikie dblaikie at gmail.com
Sun Mar 9 21:32:38 PDT 2014


On Mar 9, 2014 6:57 PM, "Richard Smith" <richard at metafoo.co.uk> wrote:
>
> On Sun, Mar 9, 2014 at 6:37 PM, Arthur O'Dwyer <arthur.j.odwyer at gmail.com>
wrote:
>>
>> On Sun, Mar 9, 2014 at 12:14 AM, Ahmed Charles <acharles at outlook.com>
wrote:
>> > ________________________________
>> >> Date: Fri, 7 Mar 2014 14:15:32 -0800
>> >> Subject: Re: r203293 - [C++11] Revert uses of lambdas with
array_pod_sort.
>> >> From: richard at metafoo.co.uk
>> >> To: arthur.j.odwyer at gmail.com
>> >> CC: cfe-commits at cs.uiuc.edu
>> >>
>> >> On Fri, Mar 7, 2014 at 2:10 PM, Arthur O'Dwyer <
arthur.j.odwyer at gmail.com> wrote:
>> >>
>> >>> - The spaceship operator <=> is equivalent to (a < b) ? -1 : (a> b)
>> >>
>> >> The more usual idiom of
>> >>
>> >>    if (!=)
>> >>      return <
>> >>
>> >> naturally extends to lexicographical comparisons of multiple things. I
>> >> don't see how to do that with (a<b?-1:a>b).
>>
>> Recognizing that this is off-topic and also completely "personal
>> style", I think your classification of (a != b) ? (a < b) ? -1 : +1 :
>> 0 as "more usual" is subjective.
>
>
> I don't think I've seen it written like that. I've seen this:
>
> if (a.x != b.x) return a.x < b.x ? -1 : 1;
> if (a.y != b.y) return a.y < b.y ? -1 : 1;
> // ...
> return 0;
>
>>
>> In my subjective experience, (a < b)
>> ? -1 : (a > b) is "more usual". ;)
>>
>> If you have multiple fields in your struct, then (as Ahmed suggests)
>> the most stylish idiom is to 'tie' your fields together.
>
>
> 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.

If you're suggesting that tie+op< isn't an idiom we should generally adopt
it'd be nice to build something like it that would be appropriate. (Not
sure if there's something that should be standardized in some form as this
idiom seems like it will be common)

>
>>     template<typename T> int spaceship(const T& a, const T& b) {
>> return (a < b) ? -1 : (a > b); }  // trivial
>>
>>     struct S {
>>         int x, y, z;
>>         decltype(auto) toTuple() const { return std::tie(x,y,z); }  //
>> unfortunately annoying to type pre-C++14, but still trivial
>>     };
>>
>>     bool operator< (const S& a, const S& b) { return a.toTuple() <
>> b.toTuple(); }  // trivial
>>     int spaceship(const S& a, const S& b) { return
>> spaceship(a.toTuple(), b.toTuple()); }  // trivial
>>
>> Unfortunately I don't think C++1y has added any special library
>> support for the spaceship function, which means all the solutions
>> named so far involve computing (a.x==b.x), (a.y==b.y), etc., up to the
>> point of the first difference, TWICE. You can work around the lack of
>> std::spaceship (or std::tuple::tail or whatever you choose as your
>> missing primitive) and make the stylish solution also efficient, but I
>> won't write it here because the guts are embarrassingly ugly. :P
>>
>> -Arthur
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140309/a06c9085/attachment.html>


More information about the cfe-commits mailing list