DmitriyH
DmitriyH

Reputation: 440

The most compact way to find an element in container with the minimum value of given field

Let's we need to find an element with the minimum value of given field.

#include <boost/range/algorithm/min_element.hpp>
#include <vector>

struct Item
{
    size_t a;
    size_t b;
};

struct CompareByA
{
    bool operator()(const Item& x, const Item& y) const
    {
        return x.a < y.a;
    }
};

std::vector<Item> items;
//... fill
std::vector<Item>::const_iterator minA = boost::min_element(items, CompareByA());

What is the most compact way to do it using boost::bind or other boost features without explicit predicate struct declaration?
Maybe something like std::less and boost::bind(&Item::a) combination.

NOTE: Without using C++11 features.

Upvotes: 0

Views: 113

Answers (3)

DmitriyH
DmitriyH

Reputation: 440

Got it:

#include <boost/range/algorithm/min_element.hpp>
#include <boost/bind.hpp>
#include <vector>

struct Item
{
    size_t a;
    size_t b;
};

std::vector<Item> items;
//... fill
std::vector<Item>::iterator minA = 
    boost::min_element(items, boost::bind(&Item::a, _1) < boost::bind(&Item::a, _2));

Upvotes: 1

Jarod42
Jarod42

Reputation: 217235

You may create those helper:

template <typename T, typename M>
class CompareByMember
{
public:
    explicit CompareByMember(M m) : m(m) {}

    bool operator()(const T& x, const T& y) const
    {
        return x.*m < y.*m;
    }
private:
    M m;
};

template <typename T, typename Ret>
CompareByMember<T, Ret (T::*)> MakeCompareByMember(Ret (T::*m))
{
    return CompareByMember<T, Ret (T::*)>(m);
}

And then call

std::vector<Item>::const_iterator minA =
    boost::min_element(items, MakeCompareByMember(&Item::a));

Upvotes: 2

celtschk
celtschk

Reputation: 19721

You can just pass a function:

bool compare_by_a(Item const& x, Item const& y)
{
  return x.a < y.a;
}

// ...

std::vector<Item>::const_iterator minA = boost::min_element(items, compare_by_a);

Upvotes: 1

Related Questions