На этом шаге мы рассмотрим использование объекта функции в качестве критерия сортировки.
Программисты часто работают с сортированными коллекциями элементов, относящихся к определенному классу (например, с коллекцией объектов 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). Они не могут использоваться совместно с множествами, имеющими "обычный" или другой пользовательский критерий сортировки (в том числе участвовать в операциях присваивания). Это означает, что никакая операция с множеством не приведёт к нарушению автоматической сортировки; впрочем, можно написать объект функции, представляющий разные критерии сортировки с одним типом.
На следующем шаге мы рассмотрим объекты функций с внутренним состоянием.