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);
}
f()shall be your comparator base, I see little hope of doing this without a custom comparator of some kind (be it functor or lambda, and my money is on the former for pointer-to-member convenience). Or... I didn't understand the problem at all (its 2:30am here, really should be in bed right now).std::bind,std::placeholders::_1and related.less<>and other building blocks (such asbind), that would ultimately callf(). I already looked intobindandplaceholdersbut couldn't figure out how to do it with those.wrappedIter->f()from itsoperator*.bindwill be slower.