Lesson 4
Using Custom Comparators and Objects as Keys in C++ Maps
Topic Overview

Welcome to our exploration of using custom classes and comparators in C++ maps. In today's lesson, we'll learn how to use custom objects as keys in standard maps. This approach enhances data organization and access. With the addition of comparators, we can dictate the order in such maps, ensuring efficient and predictable data retrieval.

Quick Recap on C++ Maps

In C++, a std::map is a collection of key-value pairs where the keys are automatically ordered based on a comparison function — by default, using the < operator. This arrangement makes operations like searching for keys within a range efficient.

C++
1#include <iostream> 2#include <map> 3 4int main() { 5 std::map<char, int> map = {{'a', 1}, {'b', 2}, {'c', 3}, {'d', 4}}; 6 for(const auto& pair : map) { 7 std::cout << pair.first << ", "; 8 } // Output: a, b, c, d, 9 std::cout << std::endl; 10 11 map = {{'d', 5}, {'c', 1}, {'b', 2}, {'a', 3}}; 12 for(const auto& pair : map) { 13 std::cout << pair.first << ", "; 14 } // Output: a, b, c, d, 15 16 return 0; 17}

Notice how, in the above code snippet, iterating the map yields the same order of keys even though they have been declared differently.

Quick Recap on Custom Classes in C++

Custom classes allow us to create objects that align with our data structures — such as a Person class for employee information or a Book class for a library database. In C++, classes act as blueprints for creating objects with defined attributes and methods.

Consider this simple class example:

C++
1#include <iostream> 2#include <string> 3 4class Person { 5public: 6 Person(std::string name, int age) : name(name), age(age) {} 7 8 std::string name; 9 int age; 10}; 11 12int main() { 13 Person person("John Doe", 30); 14 std::cout << person.name << std::endl; // Outputs: John Doe 15 std::cout << person.age << std::endl; // Outputs: 30 16 return 0; 17}
Using Custom Classes as Keys in Maps

To use custom classes as keys in maps, C++ requires a way to compare these keys, often using custom comparator functions or functors.

Functors (function objects) are objects that can be called as though they are a function. This is done by defining the operator() within the class. Functors are commonly used for encapsulating operations that require state or for complex comparisons in data structures.

Here's how you can use a comparator functor for custom objects as map keys:

C++
1#include <iostream> 2#include <map> 3 4class Person { 5public: 6 Person(std::string name, int age) : name(name), age(age) {} 7 8 std::string name; 9 int age; 10}; 11 12// Comparator functor 13struct PersonCompare { 14 bool operator()(const Person& a, const Person& b) const { 15 return (a.age < b.age) || (a.age == b.age && a.name < b.name); 16 } 17}; 18 19int main() { 20 std::map<Person, std::string, PersonCompare> people; 21 22 Person john("John", 30); 23 Person alice("Alice", 25); 24 25 people[john] = "Programmer"; 26 people[alice] = "Designer"; 27 28 for(const auto& pair : people) { 29 std::cout << pair.first.name << " is a " << pair.second << std::endl; 30 } 31 // Outputs: 32 // Alice is a Designer 33 // John is a Programmer 34 35 return 0; 36}

In this code snippet, the Person class is defined with attributes name and age. We've created a PersonCompare functor to define the custom order by comparing the age first, and then name alphabetically if the ages are the same. This allows our map to store Person objects as keys, ordered by age and name.

By merging the comparison logic within a functor, we maintain a clean separation of comparison logic and enable our map to handle objects with complex attributes smoothly. This approach ensures efficient key ordering and lookup performance in our data structures.

Lesson Summary and Practice

We've explored how to use custom classes as keys in maps and how comparators work in this context in C++. As practice, try creating your own class with multiple attributes, and define a comparison functor to order these custom objects in a std::map.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.