
[C++] Custom Comparator
C++ Custom Comparator sort(iter, iter, comp) Lambda function int main(){ auto comp = [](int a, int b){ return a < b; } vector<int> = {3,6,7,2,1,9,5,4,8}; sort(vec.begin(), vec.end(), comp); // 1,2,3,4,5,6,7,8,9 } Usual boolean function bool comp(const int& a, const int& b){ return a < b; } int main(){ vector<int> = {3,6,7,2,1,9,5,4,8}; sort(vec.begin(), vec.end(), comp); // 1,2,3,4,5,6,7,8,9 } Old solution using struct/class with () operator struct cmp { bool operator() (int a, int b) const { return a < b; } }; int main(){ vector<int> = {3,6,7,2,1,9,5,4,8}; sort(vec.begin(), vec.end(), comp()); // 1,2,3,4,5,6,7,8,9 } priority_queue(element, container, comp) Modern C++20 Solution(lambda) We can use lambda function as comparator. As usual, comparator should return boolean value, indicating whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines. int main(){ auto comp = [](int a, int b){ return a < b; } vector<int> vec = {3,6,7,2,1,9,5,4,8}; priority_queue<int, vector<int, decltype(comp)> pq; for (int num : vec) pq.push(num); while (!pq.empty()) { cout << pq.top() << " "; // 9,8,7,6,5,4,3,2,1 pq.pop(); } cout << endl; } Modern C++11 Solution(lambda) Before C++20 we need to pass lambda function as argument to set constructor. int main(){ auto comp = [](int a, int b){ return a < b; } vector<int> vec = {3,6,7,2,1,9,5,4,8}; priority_queue<int, vector<int, decltype(comp)> pq(comp); for (int num : vec) pq.push(num); while (!pq.empty()) { cout << pq.top() << " "; // 9,8,7,6,5,4,3,2,1 pq.pop(); } cout << endl; } Usual function Make comparator as usual boolean function bool comp(int a, int b){ return a < b; } int main(){ vector<int> vec = {3,6,7,2,1,9,5,4,8}; priority_queue<int, vector<int, decltype(&comp)> pq(comp); // priority_queue<int, vector<int, decltype(comp)*> pq(comp); // in C++20, constructor can be ignored the same as lambda function. for (int num : vec) pq.push(num); while (!pq.empty()) { cout << pq.top() << " "; // 9,8,7,6,5,4,3,2,1 pq.pop(); } cout << endl; } Old solution using struct/class with () operator struct cmp { bool operator() (int a, int b) const { return a < b; } }; int main(){ vector<int> = {3,6,7,2,1,9,5,4,8}; priority_queue<int, vector<int>, comp> pq(vec.begin(), vec.end()); while (!pq.empty()) { cout << pq.top() << " "; // 9,8,7,6,5,4,3,2,1 pq.pop(); } cout << endl; } Alternative solution: create struct/class from boolean function bool comp(int a, int b){ return a < b; } #include <type_traits> using Cmp = integral_constant<decltype(&comp), &comp>; int main(){ vector<int> = {3,6,7,2,1,9,5,4,8}; priority_queue<int, vector<int, decltype(&comp)> pq(comp); for (int num : vec) pq.push(num); while (!pq.empty()) { cout << pq.top() << " "; // 9,8,7,6,5,4,3,2,1 pq.pop(); } cout << endl; }