Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП.doc
Скачиваний:
77
Добавлен:
07.03.2016
Размер:
1.78 Mб
Скачать

11.2 Функціональні об'єкти

Функціональним об'єктом називається клас, в якому визначена операція виклику функції (див. розділ 5.6). Ці об'єкти використовуються як параметри стандартних алгоритмів для завдання призначених для користувача критеріїв порівняння об'єктів або способів їх обробки. У тих алгоритмах, де в якості параметру можна використовувати функціональний об'єкт, можна використовувати і вказівку на функцію. При цьому застосування функціонального об'єкту може виявитися ефективнішим, оскільки операцію () можна визначити як вбудовану.

Стандартна бібліотека надає безліч функціональних об'єктів, необхідних для її ефективного використання. Вони описані в заголовному файлі <functional>.

У стандартній бібліотеці визначені шаблони функціональних об'єктів для операцій порівняння і логічних операцій, визначених в мові C++. Вони повертають значення типу bool, тобто є предикатами.

Таблиця 11.2. Предикати стандартної бібліотеки

Ім’я

Тип

Результат

equal_to

бінарний

x == у

not_equal_to

бінарний

x != у

greater

бінарний

x > у

less

бінарний

x < у

greater_equal

бінарний

x>= у

less_equal

бінарний

x<= у

log1cal_ancl

бінарний

x&& у

log1cal_or

бінарний

x || y

log1cal_not

унарний

!x

Нижче приведений шаблон об'єкту equal_to (решта об'єктів описана аналогічним чином):

template <class Т> struct equal_to:

binary_function<T, Т, bool>

{

bool operator()(const T& x, const T& y) const

{

return x == y;

}

};

Програміст може описати власні предикати для визначення критеріїв порівняння об'єктів. Це необхідно, коли контейнер складається з елементів призначеного для користувача типу.

За допомогою бінарних предикатів можна порівнювати два різні об'єкти. Часто потрібно порівняти об'єкт не з іншим об'єктом, а з константою. Щоб використовувати для цього той же самий предикат, потрібно зв'язати один з двох його аргументів з константою. Для цього використовуються зв’язувачі bind2nd і bindlst, що дозволяють пов'язати з конкретним значенням відповідно другий і перший аргумент бінарної функції. Зв’язувачі реалізовані в стандартній бібліотеці як шаблони функцій, що приймають першим параметром функціональний об'єкт f з двома аргументами, а другим – прив'язуване значення value. Результатом виклику функції є функціональний об'єкт, створений з вхідного об'єкту f шляхом "підстановки" value в його перший або другий аргумент.

Припустимо, потрібно обчислити кількість елементів цілочисельного масиву, які менше 40:

#include <iostream>

#include <functional>

#include <algorithm>

using namespace std;

Void main()

{

int m[8] = {45, 65, 36, 25, 674, 2, 13, 35};

cout<<count_if(m, m + 8, bind2nd(less<int>(), 40));

}

У цій програмі для підрахунку кількості елементів застосовується алгоритм стандартної бібліотеки count_if. Для його використання потрібно підключити заголовний файл <functional>. Першими двома параметрами count_if мають бути ітератори, які визначають початок і кінець оброблюваної послідовності. В якості ітераторів масиву використовуються вказівки на його елементи. Третій параметр функції count_if має бути бінарною функцією або функціональним об'єктом. Функція bind2nd перетворює умову порівняння х < у в умову х < 40.

Для того, щоб застосовувати зв’язувачі до звичайних вказівок на функції, потрібні спеціальні перетворювачі, або адаптери. Стандартна бібліотека визначає два функціональні об'єкти – вказівку на унарну функцію pointer_to_unary_function та вказівку на бінарну функцію pointer_to_binary_ function, а також дві функції-адаптери ptr_fun з одним і двома аргументами, які перетворять переданий їм в якості параметру вказівку на функцію у функціональний об'єкт.

Приклад застосування адаптера функції:

#include <iostream>

#include <functional>

#include <algorithm>

using namespace std;

struct A{int x, y;};

bool lss(A al,A a2){return al.x < a2.x;}