Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find max element of a vector with user defined predicate

Tags:

c++

c++11

stl

I need to find the maximum element of a vector. I want to use max_element from the STL library.

The code I have tried is:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class A
{
public:
    A(int _size, long _len) : size(_size), len(_len){}

    int size;
    long len;
};

bool CompareMaxA(const A& _a, const A& _b)
{
    return _a.len > _b.len;
}

int main() {

    vector<A> vec;
    A a1(3, 10);
    A a2(5, 30);
    vec.push_back(a1);
    vec.push_back(a2);

    auto it = max_element(vec.begin(), vec.end(), CompareMaxA);

    cout << "max = " << it->len;

    return 0;
}

I get max = 10, instead of max = 30. Why?

like image 911
Remi Bettan Avatar asked Nov 18 '25 14:11

Remi Bettan


1 Answers

Your comparison function does the wrong thing. It returns true whenever _a.len is greater than _b.len, but std::max_element requires a custom comparison function that returns true in exactly the opposite scenarios. From cppreference on std::max_element:

Parameters

[...]

comp - comparison function object (i.e. an object that satisfies the requirements of Compare) which returns ​true if the first argument is less than the second.

You can fix it by

bool lessThanByLen(const A& _a, const A& _b)
{
    return _a.len < _b.len;
}

auto it = max_element(vec.begin(), vec.end(), lessThanByLen);

Custom comparators used by/passed to the standard library for order relations always seek for a less-than relation. In this case, the algorithm name (max_element) indicates that a maximum shall be found.

Note that as @JeJo pointed out in the comments, you can also consider passing a lambda:

auto it = max_element(vec.begin(), vec.end(),
    [](const A& lhs, const A& rhs) { return lhs.len < rhs.len; });
like image 86
lubgr Avatar answered Nov 21 '25 05:11

lubgr



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!