C++ Academy · Lesson

Custom Comparators

Control ordering.

Lesson 4 of 413 steps

Custom Comparators is a free C++ Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the C++ Academy learning path, and your progress syncs across the web and the CoddyKit app. The C++ Academy course includes 4 lessons in total.

Why Custom Comparators?

By default, ordered containers sort with std::less (ascending). A custom comparator lets you change that order, for example descending or by a specific field.

#include <iostream>
#include <set>

int main() {
    std::set<int> ascending{3, 1, 2};
    for (int x : ascending) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Descending with std::greater

The simplest custom comparator is the standard functor std::greater, which sorts in descending order.

#include <iostream>
#include <set>
#include <functional>

int main() {
    std::set<int, std::greater<int>> s{3, 1, 2};
    for (int x : s) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Comparator on a map

The comparator is the third template parameter of std::map. Here keys sort from high to low.

#include <iostream>
#include <map>
#include <functional>

int main() {
    std::map<int, std::string, std::greater<int>> m{
        {1, "one"}, {3, "three"}, {2, "two"}
    };
    for (const auto& [k, v] : m) std::cout << k << ':' << v << ' ';
    std::cout << '\n';
    return 0;
}

How Comparators Work

A comparator is a callable taking two arguments returning true if the first should come before the second. It must define a strict weak ordering.

#include <iostream>

struct Less {
    bool operator()(int a, int b) const { return a < b; }
};

int main() {
    Less cmp;
    std::cout << std::boolalpha << cmp(2, 5) << '\n';
    std::cout << cmp(5, 2) << '\n';
    return 0;
}

A Custom Struct Comparator

Define your own functor struct with operator() and pass its type as the comparator.

#include <iostream>
#include <set>

struct ByAbs {
    bool operator()(int a, int b) const {
        return (a < 0 ? -a : a) < (b < 0 ? -b : b);
    }
};

int main() {
    std::set<int, ByAbs> s{-5, 3, -1, 4};
    for (int x : s) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Sorting Strings by Length

Comparators can compare any property. Here strings order by length, then alphabetically as a tiebreaker.

#include <iostream>
#include <set>
#include <string>

struct ByLen {
    bool operator()(const std::string& a, const std::string& b) const {
        if (a.size() != b.size()) return a.size() < b.size();
        return a < b;
    }
};

int main() {
    std::set<std::string, ByLen> s{"bbb", "a", "cc", "dd"};
    for (const auto& x : s) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Why Tiebreakers Matter

If your comparator says neither element comes before the other, the container treats them as equal. In a set that means one gets dropped as a duplicate.

#include <iostream>
#include <set>
#include <string>

struct LenOnly {
    bool operator()(const std::string& a, const std::string& b) const {
        return a.size() < b.size();
    }
};

int main() {
    std::set<std::string, LenOnly> s{"ab", "cd", "x"};
    std::cout << s.size() << " elements\n";
    return 0;
}

Lambdas as Comparators

You can use a lambda by passing its type via decltype and the lambda itself to the constructor.

#include <iostream>
#include <set>

int main() {
    auto cmp = [](int a, int b) { return a > b; };
    std::set<int, decltype(cmp)> s(cmp);
    s.insert(1);
    s.insert(3);
    s.insert(2);
    for (int x : s) std::cout << x << ' ';
    std::cout << '\n';
    return 0;
}

Comparators in priority_queue

Comparators also configure std::priority_queue. With std::greater it becomes a min-heap.

#include <iostream>
#include <queue>
#include <vector>
#include <functional>

int main() {
    std::priority_queue<int, std::vector<int>, std::greater<int>> pq;
    pq.push(5); pq.push(1); pq.push(3);
    while (!pq.empty()) { std::cout << pq.top() << ' '; pq.pop(); }
    std::cout << '\n';
    return 0;
}

Comparing Pairs

To sort a set of pairs by the second element, write a comparator that inspects .second.

#include <iostream>
#include <set>
#include <utility>

struct BySecond {
    bool operator()(const std::pair<int,int>& a, const std::pair<int,int>& b) const {
        return a.second < b.second;
    }
};

int main() {
    std::set<std::pair<int,int>, BySecond> s{{1, 9}, {2, 3}, {3, 6}};
    for (const auto& p : s) std::cout << p.first << ':' << p.second << ' ';
    std::cout << '\n';
    return 0;
}

Transparent Comparators

Using std::less<> (with empty angle brackets) enables heterogeneous lookup in C++14, avoiding temporary key conversions.

#include <iostream>
#include <set>
#include <functional>

int main() {
    std::set<int, std::less<>> s{1, 2, 3};
    std::cout << (s.find(2) != s.end() ? "found" : "no") << '\n';
    return 0;
}

Quick Check

Test your understanding of how comparators define equality.

Recap

You learned that custom comparators:

  • change ordering via the container's comparator template parameter
  • can be std::greater, a functor struct, or a lambda (via decltype)
  • define equality by equivalence, so always include a tiebreaker to avoid losing distinct elements

Next course: fast hash-based lookup with std::unordered_map.

Free to start

Learn C++ with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
51
Lessons
203

Frequently Asked Questions

Is the “Custom Comparators” lesson free?

Yes — any 3 lessons of the C++ Academy learning path, including “Custom Comparators”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The C++ Academy course includes 4 lessons in total.

What will I learn in “Custom Comparators”?

Control ordering. You practise C++ Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C++ Academy?

No prior experience is required. C++ Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “Custom Comparators” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C++ Academy lesson?

Yes. Every C++ Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. std::map
  2. std::set
  3. multimap and multiset
  4. Custom Comparators
← Back to C++ Academy