std algorithms with pointer to member as comparator/"key"

algorithm, c++, c++11, pointer-to-member

Solution

You can use `std::mem_fn` (or `std::tr1::mem_fn`)

int main()
{
    std::vector<MyType> vec;

    auto m = std::max_element(std::begin(vec), std::end(vec), compare_by(std::mem_fn(&MyType::field)));
}

Of course, this assumes that you have a utility like `compare_by` in your toolbox (as you should :)):

template <typename F>
struct CompareBy {
    explicit CompareBy(F&& f) : f(std::forward<F>(f)) {}
    template <typename U, typename V> 
        bool  operator()(U const& u, V const& v) const {
            return f(u) < f(v);
        }

private:
    F f;
};

template <typename F>
CompareBy<F> compare_by(F&& f) { return CompareBy<F>(std::forward<F>(f)); }

See it Live On Coliru

Problem

I often find myself using `std::sort`, `std::max_element`, and the like with a lambda that simply invokes a member function ``` std::vector<MyType> vec; // populate... auto m = std::max_element(std::begin(vec), std::end(vec), [](const MyType& a, const MyType& b) { return a.val() < b.val()}) ``` this feels like a waste of characters and a loss of clarity. I'm aware that I could write another function/callable and pass a function pointer/callable object to these algorithm functions, but I often need to do this sort-by just once in a program and it doesn't strike me as a good way of addressing the problem. What I want to do, ideally is say: ``` auto m = std::max_element(std::begin(vec), std::end(vec), &MyType::val); ``` and have the objects be sorted by their `val()`s. Is there some part of the stdlib I'm overlooking that could assist me with this? or another simple way of doing it? I'd like to make what this is sorting or searching by as obvious as possible. I'm aware that just `&MyType::val` isn't enough, I am looking for something that could perhaps wrap it, or provide a similar functionality without obscurring the meaning.

Original source

Related problems