Say I have class A
with member function int f() { return m_; }
where m_
is a data member. I have a vector<A>
called vec
, and I want to find the object with maximum m_
value in vec
using std::max_element
. I can do it with a lambda:
auto cmp = [] (A& x, A& y) { return x.f() < y.f(); };
A& max_elem = *std::max_element(vec.begin(), vec.end(), cmp);
Is there some bind
(or some such) trickery that will allow me to do it without a lambda and without defining my own comparator from scratch? Please don't suggest better ways to solve the max finding problem. It's only an example. The general question is how to wrap a function object that takes more than one argument (e.g., std::less<int>
, which I would use as the comparator in the above example) in such a way that that arguments sent to it go through some other function (or member function) before getting to it.
Yes, there is:
using namespace std::placeholders;
A& max = *std::max_element(begin(vec), end(vec)
, std::bind(
&std::less<int>::operator()
, std::less<int>()
, std::bind(&A::f, _1)
, std::bind(&A::f, _2)
)
);
Live example
However, if I ever saw this in code review, I'd immediately say "turn that ugliness into a lambda."
Thanks to @n.m. for poining out that the code can be shortened a bit:
using namespace std::placeholders;
A& max = *std::max_element(begin(vec), end(vec)
, std::bind(
std::less<int>()
, std::bind(&A::f, _1)
, std::bind(&A::f, _2)
)
);
Live example
I still consider a lambda more readable, though. Bear in mind that you can use a lambda directly in the call to max_element()
(no need for the variable cmp
in your original code).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With