Skip to main content

Section 21.6 Comparisons and Functors

In the last section we saw how we could control the ordering of elements in a set by changing the definition of operator< for our custom types.
But what if our data type has a operator< that we do not want to (or can’t) change, yet we want to use a different ordering for a specific set? In that case, we can provide a custom comparison function to the set when we declare it using syntax like this:
set<Person, PersonAgeComparer> peopleByAge;
In that sample, PersonAgeComparer must be the name of something that will take two Persons and return a bool indicating whether the first should be considered less than the second according to the desired ordering.
Although you might assume that thing would be a function (and it can be), it is generally easier in C++ to use a functor for jobs like this. A functor is a class or struct that can behave like a function because it defines an operator().
Here is an example of a functor that could be used to compare two Person objects by their age:
struct PersonAgeComparer {
  bool operator()(const Person& a, const Person& b) const {
    return a.age > b.age; // Compare by age descending
  }
};
This PersonAgeComparer struct defines an operator(). That means that you can take an instance of PersonAgeComparer and use it like a function. When you do so, it takes two Person params and returns true or false.
The expected behavior of a comparison functor defined this way is that it takes two parameters. We will call them a and b. The functor should return true if a should come before b in the desired ordering, and false otherwise. Thus, in the example above, the functor returns true if a’s age is greater than b’s age, which results in ordering people by age in descending order (oldest first).
Given that functor, we can now declare a set that uses it to order People by age even though the Person struct itself defines operator< to compare by name.
Listing 21.6.1.
This technique is especially important if you do not even have control over the definition of the type you are storing in the set.
Say you wanted to store a set of standard strings but wanted to order them in reverse alphabetical order. You cannot change the definition of std::string to modify its operator<, but you can define your own functor to do the comparison you want and provide that to the set.

Checkpoint 21.6.1.

You have attempted of activities on this page.