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.
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.
You have attempted of activities on this page.
