Обратные вызовы в C++ - [18]
4.3.3. Объявление предикатов
После описанной модификации первоначального кода у нас остается одна проблема: как выполнять операции сравнения для нечисловых данных, например, структур? Ведь алгоритм не знает, да и не должен знать, по каким правилам нужно их сравнивать. Выход очевидный – делегировать эти операции создателю данных. Для этого будем использовать обратный вызов «вычисление по запросу» (п. 1.2.2). Параметрами вызова будут экземпляры данных, а возвращать он будет результат сравнения. Оформленный таким образом вызов называется предикатом.
Предикат – это выражение, принимающее одну или более величину и возвращающее результат булевого типа.
Объявим предикат как дополнительный параметр шаблона (Листинг 33).
>template
>void sort_bubble(Data* data, size_t size, Predicate less) // (2)
>{
> for (size_t i = 0; i < size – 1; i++)
> {
> for (size_t j = 0; j < size – i – 1; j++)
> {
> if (less (data[j + 1], data[j])) // (3)
> {
> Data temp = data[j];
> data[j] = data[j + 1];
> data[j + 1] = temp;
> }
> }
> }
>}
По сравнению с предыдущим кодом из Листинг 32 изменения здесь следующие: в объявлении шаблона (строка 1) объявлен дополнительный параметр – предикат, в функции шаблона (строка 2) предикат объявляется как дополнительный входной параметр, в строке 3 вместо операции сравнения происходит вычисление предиката.
В качестве предикатов могут использоваться:
• глобальные функции;
• статические функции класса;
• перегруженные операторы;
• лямбда-выражения.
В Листинг 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 – сортировка в соответствии с заданными правилами.
4.3.4. Предикаты по умолчанию
Итак, мы рассмотрели, как с помощью предикатов реализуется операция вычисления меньшего из двух элементов. Но далеко не всегда требуется сортировать сложные структуры данных, зачастую это всего лишь обычные числовые значения. В этом случае придется объявлять предикат с тривиальной реализацией (сравнить два числа). Может также случиться, что у нас в объявлении элемента данных уже реализован перегруженный оператор сравнения, тогда в предикате придется дублировать его код. Всего этого можно избежать, если объявить предикат, который будет использоваться по умолчанию. Реализация приведена в Листинг 35.
>template
>struct default_less
>{
> bool operator()(const Data& x, const Data& y) // (2)
> {
> return x < y;
> }
>};
>template

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)

Что такое ГЕЙМДИЗАЙН? Это не код, графика или звук. Это не создание персонажей или раскрашивание игрового поля. Геймдизайн – это симулятор мечты, набор правил, благодаря которым игра оживает. Как создать игру, которую полюбят, от которой не смогут оторваться? Знаменитый геймдизайнер Тайнан Сильвестр на примере кейсов из самых популярных игр рассказывает как объединить эмоции и впечатления, игровую механику и мотивацию игроков. Познакомитесь с принципами дизайна, которыми пользуются ведущие студии мира! Создайте игровую механику, вызывающую эмоции и обеспечивающую разнообразие.

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.