Обратные вызовы в C++ | страница 36
В качестве предикатов могут использоваться:
• глобальные функции;
• статические функции класса;
• перегруженные операторы;
• лямбда-выражения.
В Листинг 34 продемонстрировано использование предикатов различных типов.
>struct DBRecord // (1)
>{
> char firstName[50];
> char lastName[50];
>};
>bool CompareByFirstName(const DBRecord& rec1, const DBRecord& rec2) // (2)
>{
> return strcmp(rec1.firstName, rec2.firstName) < 0;
>}
>bool CompareByLastName(const DBRecord& rec1, const DBRecord& rec2) // (3)
>{
> return strcmp(rec1.lastName, rec2.lastName) < 0;
>}
>class SortRules // (4)
>{
>public:
> enum {SORT_ASC = 1, SORT_DESC = 2} sortDirect; // (5)
> enum { SORT_FIRST_NAME = 1, SORT_LAST_NAME = 2 } sortWhat; // (6)
> bool operator () (const DBRecord& rec1, const DBRecord& rec2) const // (7)
> {
> if (sortDirect == SORT_ASC)
> {
> if (sortWhat == SORT_FIRST_NAME)
> {
> return strcmp(rec1.firstName, rec2.firstName) < 0;
> }
> else
> {
> return strcmp(rec1.lastName, rec2.lastName) < 0;
> }
> }
> else
> {
> if (sortWhat == SORT_FIRST_NAME)
> {
> return strcmp(rec1.firstName, rec2.firstName) > 0;
> }
> else
> {
> return strcmp(rec1.lastName, rec2.lastName) > 0;
> }
> }
> }
>};
>int main()
>{
>DBRecord dbRecArray[10]; // (8)
>//Read from database
>sort_bubble(dbRecArray, 10, CompareByFirstName); // (9)
>sort_bubble(dbRecArray, 10, CompareByLastName); // (10)
>sort_bubble(dbRecArray, 10, [](const DBRecord& rec1, const DBRecord& rec2) // (11)
>{
>return strcmp(rec1.firstName, rec2.firstName) < 0;
>});
>sort_bubble(dbRecArray, 10, [](const DBRecord& rec1, const DBRecord& rec2) // (12)
>{
>return strcmp(rec1.lastName, rec2.lastName) < 0;
>});
>SortRules rules; // (13)
>rules.sortWhat = SortRules::SORT_LAST_NAME; // (14)
>rules.sortDirect = SortRules::SORT_ASC; // (15)
>sort_bubble(dbRecArray, 10, rules); // (16)
>}
В строке 8 объявлен массив структур, сами структуры объявлены в строке 1 (предположим, что это записи базы данных). В строке 9 и 10 происходит сортировка массива с использованием предикатов в виде внешней функции, в строках 11 и 12 – в виде лямбда-выражений.
В строке 13 объявлен предикат как экземпляр класса. Если посмотреть объявление класса (строка 4), то можно увидеть, что он позволяет осуществлять настройку правил: в строке 5 имеется переменная для настройки порядка сортировки (возрастание либо убывание), в строке 6 имеется переменная для настройки поля сортировки. В строке 7 реализован перегруженный оператор, который в соответствии с настроенными правилами вычисляет, является ли первый элемент меньше второго. В строках 14 и 15 производится настройка предиката, в строке 16 – сортировка в соответствии с заданными правилами.