Обратные вызовы в C++ | страница 35
> {
> int temp = data[j];
> data[j] = data[j + 1];
> data[j + 1] = temp;
> }
> }
> }
>}
Описанный код работает с числами. Параметризуем типы (Листинг 32):
>template
>void sort_bubble(Data* data, size_t size) // (2)
>{
> for (size_t i = 0; i < size – 1; i++)
> {
> for (size_t j = 0; j < size – i – 1; j++)
> {
> if (data[j + 1] < data[j])
> {
> Data temp = data[j]; // (3)
> data[j] = data[j + 1];
> data[j + 1] = temp;
> }
> }
> }
>}
По сравнению с предыдущим листингом изменений здесь совсем немного: в строке 1 объявлен параметр шаблона для типа данных, в реализации функции вместо типа данных подставляется параметр шаблона (строки 2 и 3). Теперь мы можем делать сортировку для любого типа данных: мы просто вызываем функцию и передаем ей требуемую переменную-массив, а компилятор сгенерирует код для соответствующего массива.
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 вместо операции сравнения происходит вычисление предиката.