There's a number of ways you can supply a predicate to a algorithm. Below you'll see a number of examples of how this can be done. Here's a summary of the calls to std::max_element()
:
//here we're using an in-place lambda
A& max_elem = *std::max_element(vec.begin(), vec.end(), [](A& x, A&y){ return x.f() < y.f(); });
// here we're binding to a non-static member function
A& max_elem = *std::max_element(vec.begin(), vec.end(), std::bind(&A::compare, A(0), std::placeholders::_1, std::placeholders::_2));
// here we're binding to a non-member function
A& max_elem = *std::max_element(vec.begin(), vec.end(), std::bind(gcompare, std::placeholders::_1, std::placeholders::_2));
// here we're using the non-member function without using bind
A& max_elem = *std::max_element(vec.begin(), vec.end(), gcompare);
We could also use std::function
.
Here's the full test source code so that you can play with it yourself:
class A
{
int m_ = 0;
public:
A(int max) : m_(max)
{
}
A(const A& that)
{
m_ = that.m_;
}
A& operator=(const A& that)
{
m_ = that.m_;
}
int f() const
{
return m_;
}
bool compare(const A&x, const A&y) const
{
return x.m_ < y.m_;
}
static bool scompare(const A&x, const A&y)
{
return x.m_ < y.m_;
}
};
static bool gcompare(const A&x, const A&y)
{
return x.f() < y.f();
}
int main()
{
std::vector<A> vec;
vec.emplace_back(5);
vec.emplace_back(7);
vec.emplace_back(4);
vec.emplace_back(9);
vec.emplace_back(12);
vec.emplace_back(1);
A& max_elem = *std::max_element(vec.begin(), vec.end(), [](A& x, A&y){ return x.f() < y.f(); });
A& max_elem = *std::max_element(vec.begin(), vec.end(), std::bind(&A::compare, A(0), std::placeholders::_1, std::placeholders::_2));
A& max_elem = *std::max_element(vec.begin(), vec.end(), std::bind(gcompare, std::placeholders::_1, std::placeholders::_2));
A& max_elem = *std::max_element(vec.begin(), vec.end(), gcompare);
}