На этом шаге мы рассмотрим использование объекта функции в качестве критерия сортировки.
Программисты часто работают с сортированными коллекциями элементов, относящихся к определенному классу
(например, с коллекцией объектов Person). Но предположим, сортировка объектов должна осуществляться не
обычным оператором <, а по специальному критерию, оформленному в виде функции. В таких случаях на помощь
приходят объекты функций. Рассмотрим следующий пример:
#include <iostream> #include <string> #include <set> #include <algorithm> using namespace std; class Person { public: string firstname const; string lastname const; . . . }; // Класс функции-предиката // - оператор () сравнивает два объекта Person class PersonSortCriterion { public: bool operator() (const Person& p1, const Person& p2) const { // Первый объект Person меньше второго, // - если фамилия в первом объекте меньше фамилии во втором объекте; // - или если фамилии равны, а имя в первом объекте меньше. return p1.lastname()<p2.lastname() || (!(p2.lastname()<p1.lastname()) && p1.firstname()<p2.firstname()); } }; int main() { // Объявление типа множества со специальным критерием сортировки typedef set<Person,PersonSortCriterion> PersonSet; // Создание коллекции PersonSet coll; . . . // Выполнение операций с элементами PersonSet::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { . . . } . . . }
Множество coll использует специальный критерий сортировки PersonSortCriterion, определенный в
виде объекта функции. PersonSortCriterion определяет оператор () так, что он сравнивает два объекта Person
по полю фамилии, а если они равны - по имени. Конструктор coll автоматически создает экземпляр класса
PersonSortCriterion, чтобы элементы сортировались в соответствии с этим критерием.
Обратите внимание: критерий сортировки PersonSortCriterion является типом. Следовательно, он может
передаваться в аргументе шаблона множества. Если бы критерий был оформлен в виде обычной функции, это было
бы невозможно.
Все множества с данным критерием сортировки образуют отдельный тип (в данном примере он называется PersonSet).
Они не могут использоваться совместно с множествами, имеющими "обычный" или другой пользовательский критерий
сортировки (в том числе участвовать в операциях присваивания). Это означает, что никакая операция с множеством не
приведёт к нарушению автоматической сортировки; впрочем, можно написать объект функции, представляющий разные
критерии сортировки с одним типом.
На следующем шаге мы рассмотрим объекты функций с внутренним состоянием.