Overloaded <pair operator is not used in sorting

I overloaded less than the operation for pair<int,int> so that I can sort the vector in a certain way. I want it to be in ascending order according to the first key of the pair, and if the first keys are equal, then I would like it to be in descending order for the second key.

The problem is that the sort function does not use the overloaded operator < , but if < is called for 2 pairs, the return result is what I expect. I have attached the code snippet below, which I use for testing:

 #include <iostream> #include <vector> #include <algorithm> using namespace std; bool operator<(pair<int, int> &a, pair<int, int> &b) { if (a.first < b.first) return true; else if ((a.first == b.first) && (a.second > b.second)) return true; return false; } int main() { vector<pair<int, int>> test {make_pair(1,10), make_pair(3,4), make_pair(3,8), make_pair(6, 23), make_pair(1,6)}; sort(test.begin(), test.end()); for (int i = 0; i < test.size(); i++) cout << test[i].first << " - " << test[i].second << " "; cout << endl; auto a = make_pair(3,4); auto b = make_pair(3,8); cout << (a < b) << endl; return 0; } 

Input vector {(1,10), (3,4), (3,8), (6,23), (1,6)} .

I expect the result to be {(1,10), (1,6), (3,8), (3,4), (6,23)} .

The result obtained is {(1,6), (1,10), (3,4), (3,8), (6, 23)} .

As you can see, the result is the one you get with the standard < operator without overloading. So I thought this could be a problem, and checked (3,4) < (3,8) . In this case, the answer was returned as false, according to my overloaded operator. So where am I going wrong? Why doesn't sort overloaded operator work? There are different questions to questions about such problems, but they could not find anything that would help.

+5
source share
2 answers

There is already an operator< for pairs in the std and one that is found in the version of std::sort that you are using. Your overload has never been found. Use a named predicate instead:

 struct MyPairComparator { bool operator()(const std::pair<int, int> & a, const std::pair<int, int> & b) const { // ... } }; sort(test.begin(), test.end(), MyPairComparator()); // ADL, maybe // ^^^^^^^^^^^^^^^^^^ 

In addition, the predicate must be called with constant values, so either accept arguments by value or by reference const.

Note that sort lives in the std . In contrast, when you use the < expression in main , your own overload in the global namespace is indeed found.

+11
source

It seems you are using the C ++ 11 compiler, fixing and simplifying the use of lambda functions. Sort of

 sort(test.begin(), test.end(), [](const pair<int, int> & a, const pair<int, int> & b) { if (a.first < b.first) return true; else if ((a.first == b.first) && (a.second > b.second)) return true; return false; }); 
+1
source

All Articles