Similar presentations:
Понятие объектов функций
1. Понятие объектов функций
2. Объекты функций
Объекты функций (function object),или функторы (functor), могли бы
показаться чем-то экзотическим или
пугающим, но в сущности вы,
вероятно, их уже видели, а
возможно, и использовали, еще не
понимая
этого.
3. Концепция объектов функций и предикатов
На концептуальном уровнеобъекты функций — это
объекты, работающие как
функции.
4. Концепция объектов функций и предикатов
Однако на уровне реализацииобъекты функций — это объекты
класса, реализующего оператор
o p e r a t o r ( ).
5. Концепция объектов функций и предикатов
Хотя функции и указатели на функциютакже могут быть классифицированы
как объекты функций, здесь речь идет
об объекте класса, реализующего
оператор o p e r a t o r () для хранения
его состояния (т.е. значения в атрибутах
класса), что делает его применимым с
алгоритмами стандартной библиотекой
шаблонов (STL).
6. Концепция объектов функций и предикатов
Объекты функции, как правило,используются при работе с
библиотекой STL и
подразделяются на следующие
типы:
7. Концепция объектов функций и предикатов
Унарная функция (unary function).Функция вызывается с одним
аргументом, например f ( х ) .
Когда унарная функция
возвращает значение типа b o o
l, она называется предикатом
(predicate).
8. Концепция объектов функций и предикатов
Бинарная функция (binary function).Функция вызывается с двумя
аргументами, например f (х, у ) .
Когда бинарная функция возвращает
значение типа b o o l, она называется
бинарным предикатом (binary
predicate).
9. Концепция объектов функций и предикатов
Объекты функций,возвращающие значение типа b
o o l, обычно используются в
алгоритмах при принятии
решений.
10. Концепция объектов функций и предикатов
Объект функции,объединяющий два объекта
функции, называется адаптивным
объектом функции (adaptive
function object).
11. Унарные функции
Функции с одиночнымпараметром являются
унарными.
12. Унарные функции
Унарная функция может делать нечтоочень простое, например отобразить
элемент на экране. Это может быть
реализовано следующим образом:
// Унарная функция
template <typename elementType>
void FuncDisplayElement (const elementType & element)
{
cout << element << ' ';
};
13. Унарные функции
Функция FuncDisplayElement() получает один параметршаблонного типа elementType, отображаемый на
консоли с использованием оператора s t d ::c o u t . Та
же функция может иметь и другое представление, в
котором реализация функции фактически содержится
оператором o p e r a t o r () класса или структуры:
// Структура, способная вести себя как унарная функция
template <typename elementType>
struct DisplayElement
{
void operator () (const elementType& element) const
{
cout << element << ' ';
}
};
14. Унарные функции
Обратите внимание, что DisplayElement это структура.Если бы это былкласс, то оператор operator
() должен был бы иметь модификатор
доступа
public.
Структура сродни классу, но ее члены
являются открытыми по умолчанию.
15. Унарные функции
Любая из этих реализаций можетприменяться с алгоритмом библиотеки
STL for_each, чтобы отобразить
содержимое коллекции на экране, по
одному элементу за раз, как
представлено в листинге 21.1.
16. ЛИСТИНГ 21.1. Отображение содержимого коллекции на экране с использованием унарной функции
17. ЛИСТИНГ 21.1. Отображение содержимого коллекции на экране с использованием унарной функции
18. ЛИСТИНГ 21.1. Отображение содержимого коллекции на экране с использованием унарной функции
19. ЛИСТИНГ 21.1. Отображение содержимого коллекции на экране с использованием унарной функции
Стандарт C++11 вводит лямбда-выражения, являющиесябезымянными объектами функций.
Версия лямбда-выражения структуры DisplayElement<T>
из листинга 21.1 делает весь код компактней, включая
определение структуры и ее применение в трех строках
функции main (), если заменить строки 32-34:
// Отобразить массив целых чисел, используя лямбдавыражения
for_each ( vecIntegers.begin () // Начало диапазона
, vecIntegers.end () // Конец диапазона
, [] (int& Element) {cout « element « ' '} );
// Лямбда-выражение
20. ЛИСТИНГ 21.1. Отображение содержимого коллекции на экране с использованием унарной функции
Таким образом, лямбда-выражения - этофантастическое преимущество C++
и вы изучите их на последующих
лекциях, где Листинг 22.1 будет
демонстрировать использование лямбдафункции в алгоритме
for_each () для отображения
содержимого контейнера вместо объекта
функции, как в листинге 21.1.
21. Унарные функции
Реальное преимущество использованияобъекта функции, реализованного в
структуре, становится очевидным, когда вы в
состоянии использовать объект структуры
для хранения информации.
Это нечто, чего функция FuncDisplayElement
() не может сделать в отличие от структуры,
поскольку структура способна хранить
атрибуты, кроме оператора o p e r a t o r ().
22. Унарные функции
Вот несколько измененная версия, в которойиспользуются атрибуты:
23. Унарные функции
В приведенном выше фрагменте структураDisplayElementKeepCount немного модифицирована по
сравнению с предыдущей версией.
Оператор o p e r a t o r () больше не является
константной функцией-членом, поскольку он
осуществляет инкремент (а следовательно, изменяет)
значения переменной-члена Count, используемой для
хранения количества ее вызовов и применяемой для
отображения данных. Этот подсчет возможен
благодаря открытому атрибуту Count.
Преимущество использования таких объектов
функции, способных хранить состояние, показано в
листинге 21.2.
24. ЛИСТИНГ 21.2. Использование объекта функции для хранения состояния
25. ЛИСТИНГ 21.2. Использование объекта функции для хранения состояния
26. ЛИСТИНГ 21.2. Использование объекта функции для хранения состояния
27. Унарный предикат
Унарная функция, котораявозвращает значение типа b o o l,
является предикатом.
Такая функция помогает
алгоритмам STL принимать
решения.
28. Унарный предикат
В листинге 21.3 приведен примерпредиката, определяющий,
является ли вводимый элемент
кратным исходному значению
29. ЛИСТИНГ 21.3. Унарный предикат, определяющий, является ли число кратным другому
30. Унарный предикат
В листинге 21.4 предикатиспользуется, как и в листинге
21.3, для определения кратности
чисел, вводимых в коллекцию,
заданному пользователем
делителю.
31. ЛИСТИНГ 21.4. Использование унарного предиката IsMultiple с алгоритмом std::find_if () для поиска в векторе элемента, кратного
введенному пользователем делителю32. ЛИСТИНГ 21.4. Использование унарного предиката IsMultiple с алгоритмом std::find_if () для поиска в векторе элемента, кратного
введенному пользователем делителю33. ЛИСТИНГ 21.4. Использование унарного предиката IsMultiple с алгоритмом std::find_if () для поиска в векторе элемента, кратного
введенному пользователем делителюЧтобы увидеть, как применение
лямбда-выражений повышает
компактность программы,
представленной в листинге 21.4,
обратите внимание на листинг 22.3
в последующих лекциях
34. Бинарные функции
Функции типа f (х , у) особенно полезны,когда они возвращают значение на
основании введенных значений.
Такие бинарные функции применяются
для хранения арифметического действия
с двумя операндами, такого как
сложение, умножение, вычитание и т.д.
35. Бинарные функции
Типичная бинарная функция, возвращающаяпроизведение входных аргументов, может
быть написана так:
36. Бинарные функции
Представляющая интерес реализация снованаходится в операторе o p e r a t o r (), который
получает два аргумента и возвращает их
произведение.
Подобные бинарные функции используются в таких
алгоритмах, как s t d : : t r a n s f o r m (), где вы
можете использовать его для умножения
содержимого двух контейнеров.
В листинге 21.5 показано применение таких
бинарных функций в алгоритме s t d : : t r a n s f o
r m ().
37. ЛИСТИНГ 21.8. Использование бинарной функции для умножения двух диапазонов
38. ЛИСТИНГ 21.8. Использование бинарной функции для умножения двух диапазонов
39. ЛИСТИНГ 21.8. Использование бинарной функции для умножения двух диапазонов
40. ЛИСТИНГ 21.8. Использование бинарной функции для умножения двух диапазонов
41. Бинарный предикат
Функция, которая получает двааргумента и возвращает значение
типа b o o l, является бинарным
предикатом.
42. Бинарный предикат
Такие функции находят применение в такихалгоритмах библиотеки STL, как s t d : : s o r t ().
Листинг 21.6 демонстрирует применение бинарного
предиката, который сравнивает две строки после
перевода их в нижний регистр. Такой предикат
применяется, например, при выполнении
независящей от регистра сортировки вектора строк.
43. ЛИСТИНГ 21.6. Бинарный предикат для сортировки строк, независящей от регистра
44. ЛИСТИНГ 21.7. Использование объекта функции класса CompareStringNoCase для независящей от регистра сортировки вектора строк
45. ЛИСТИНГ 21.7. Использование объекта функции класса CompareStringNoCase для независящей от регистра сортировки вектора строк
46. ЛИСТИНГ 21.7. Использование объекта функции класса CompareStringNoCase для независящей от регистра сортировки вектора строк
47. Бинарный предикат
Бинарные предикаты применяются во множествеалгоритмов STL.
Например, в алгоритме s t d : : u n i q u e ( ) ,
удаляющем совпадающие соседние элементы, в
алгоритме s t d : : s o r t ( ), осуществляющем
сортировку, в алгоритме s t d : : s t a b l e s o r t (),
осуществляющем сортировку в относительном
порядке, в алгоритме s t d : : t r a n s f o r m (),
позволяющем выполнить операцию с двумя
диапазонами, и во многих других алгоритмах
библиотеки STL, нуждающихся в бинарном
предикате.
48. Понятие объектов функций
ИтогиНа этой лекции вы познакомились с функторами
(или объектами функций).
Вы узнали, что объекты функций,
реализованные в структуре или классе,
полезней простых функций, поскольку они
могут использоваться также для содержания
информации состояния.
Вы получили понятие о предикатах, которые
являются специальным классом объектов
функции, и ознакомились с некоторыми
практическими примерами, демонстрирующими
их удобство.