This is a two-step process. Define a key function that should be mapped to elements, that is, that is applied before the operation that finds the maximum. Wrap things together in a lambda expression, defining a comparison to find the maximum.
auto key = [](int x){ return -abs(42 - x); }; std::max_element(l.begin(), l.end(), [key](int a, int b){ return key(a) < key(b); });
Here we must write the key that was defined outside the second lambda function. (We could also define it inside). You can also put this in a single lambda function. When 42 should be parameterized from outside the lambda, commit this as a variable:
int x = 42; std::max_element(l.begin(), l.end(), [x](int a, int b){ return -abs(x - a) < -abs(x - b); });
Note that std::max_element returns an iterator. To access the value / link to it, add it with * :
int x = 42; auto nearest = std::min_element(l.begin(), l.end(), [x](int a, int b){ return abs(x - a) < abs(x - b); }); std::cout << "Nearest to " << x << ": " << *nearest << std::endl;
You can beautifully wrap this in the find_nearest generic function:
template<typename Iter> Iter find_nearest(Iter begin, Iter end, const typename std::iterator_traits<Iter>::value_type & value) { typedef typename std::iterator_traits<Iter>::value_type T; return std::min_element(begin, end, [&value](const T& a, const T& b){ return abs(value - a) < abs(value - b); }); } auto a = find_nearest(l.begin(), l.end(), 42); std::cout << *a << std::endl;
Live demo find_nearest : http://ideone.com/g7dMYI
A higher-order function, similar to the argmax function in your question, might look like this:
template<typename Iter, typename Function> Iter argmax(Iter begin, Iter end, Function f) { typedef typename std::iterator_traits<Iter>::value_type T; return std::min_element(begin, end, [&f](const T& a, const T& b){ return f(a) < f(b); }); }
You can call this with the following code having exactly the lambda function from your question:
auto a = argmax(l.begin(), l.end(), [](int x) { return -1 * abs(42 - x); }); std::cout << *a << std::endl;
Live demo argmax : http://ideone.com/HxLMap
The only remaining difference is that this argmax function uses an iterator-based interface that matches the design of standard C ++ <algorithm> ( <algorithm> ). It is always useful to adapt your own coding style to the tools you use.
If you need a container-based interface that returns a value directly, Nawaz has provided a nice solution for which the decltype function should correctly indicate the type of the return value. I decided to keep my version so that people could see both alternative interface designs.