This code is predicated on the notion that when sorting (or using a sorted collection of items, such as with std::lower_bound) you're usually comparing a single field in each object being sorted/searched.So a typical sort might look something like:// Sort by agestd::sort(people.begin(), people.end(),     [](Person const &a, Person const &b) { return a.age < b.age; });Or:// sort by height, descending:std::sort(people.begin(), people.end(),     [](Person const &a, Person const &b) { return b.height < a.height; });Although the lambda is cleaner than C++98 code, I'd really rather be able to specify something like by(height, descending). I haven't (yet) figured out a way to (quite) get to that ideal, but I think this gets us quite a bit closer:#ifndef SORT_MEMBERS_H_#define SORT_MEMBERS_H_namespace sort {    namespace detail {        template <class FieldType, class RecordType>        struct Desc {            FieldType RecordType::*fn;        public:            Desc(FieldType RecordType::*fn) : fn(fn) {}            bool operator()(RecordType const &a, RecordType const &b) {                return b.*fn < a.*fn;            }        };        template <class FieldType, class RecordType>        struct Asc {            FieldType RecordType::*fn;        public:            Asc(FieldType RecordType::*fn) : fn(fn) {}            bool operator()(RecordType const &a, RecordType const &b) {                return a.*fn < b.*fn;            }        };    }    template <class FieldType, class RecordType>    detail::Asc<FieldType, RecordType> ascending(FieldType RecordType::*b) {        return detail::Asc<FieldType, RecordType>(b);    }    template <class FieldType, class RecordType>    detail::Desc<FieldType, RecordType> descending(FieldType RecordType::*b) {        return detail::Desc<FieldType, RecordType>(b);    }}#endifExample usage would be something like this:#include <vector>#include <algorithm>#include <iostream>#include <string>#include sort_members.hstruct Person{    std::string first_name;    std::string last_name;    int age;    friend std::ostream &operator<<(std::ostream &os, Person const &person) {        return os << person.first_name <<   << person.last_name << ,  << person.age;    }};int main() {    std::vector<Person> people = {         { John, Rambo, 42 },         { Joffrey, Baratheon, 14 },         { Kyle, Reese, 25 }     };    std::sort(people.begin(), people.end(), sort::descending(&Person::age));    std::cout << Sorted by age, descending:\n;    for (const auto& person : people)        std::cout << person << \n;    std::cout << \nSorted by last name:\n;    std::sort(people.begin(), people.end(), sort::ascending(&Person::last_name));    for (const auto& person : people)        std::cout << person << \n;}I'd welcome any comments--but I'm mostly interested in the part in the header; the file using it is just a demo, not anything very interesting in itself, beyond the fact that it demonstrates how the preceding code is used.
Select member for comparison in sort or search
c++