Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
###Cpp_лкц1_1.09_11_#дляБАК#29_01_12.doc
Скачиваний:
40
Добавлен:
29.04.2019
Размер:
6.42 Mб
Скачать

Глава 13. Итераторы и функциональные объекты

337

Отрицатели

Отрицатели notl и not2 применяются для получения противоположного унарного и бинарного предиката соответственно. Использовать отрицатели очень просто. Например, для того чтобы получить инверсию предиката less<int>(), нужно записать выражение not2(less<int>0). Оно эквивалентно greater_equal<int>.

Отрицатели применяются для инвертирования предикатов, заданных пользователем, поскольку для стандартных предикатов библиотека содержит соответствующие им противоположные объекты.

Рассмотрим реализацию отрицателей. В библиотеке описаны функциональные объекты unaryjiegate и binaryjiegate, являющиеся потомками unary_function и binary_function соответственно. Эти классы принимают в качестве параметра конструктора объект, являющийся предикатом требуемого типа:

template <class Predicate> class unaryjiegate: public

unary_function<typename Predicate::argument_type. bool>{ public:

explicit unary__negate(const Predicate& pred); bool operatorO

(const typename Predicate::argument_type& x) const:

}: Операция () возвращает инверсию предиката, notl и not2 определены как шаблоны функций, принимающих предикат и возвращающих функциональный объект:

template <class Predicate>

unary_negate<Predicate> notKconst Predicate& pred): template <class Predicate>

binary_negate<Predicate> not2(const Predicate& pred):

Связыватели

С помощью бинарных предикатов можно сравнивать два различных объекта. Часто требуется сравнить объект не с другим объектом, а с константой. Чтобы использовать для этого тот же самый предикат, требуется связать один из двух его аргументов с константой. Для этого используются связыватели bind2nd и bindlst, позволяющие связать с конкретным значением соответственно второй и первый аргумент бинарной функции.

Связыватели реализованы в стандартной библиотеке как шаблоны функций, принимающих первым параметром функциональный объект f с двумя аргументами, а вторым — привязываемое значение val ue. Результатом вызова функции является функциональный объект, созданный из входного объекта f путем «подстановки» val ue в его первый или второй аргумент.

Для описания типа возвращаемого функционального объекта в библиотеке описаны шаблоны классов binder2nd и binderlst. Ниже приведены шаблоны связыва-телей:

template <class Op. class T>

binder2nd<0p> bind2nd(const 0p& op. const T& x);

338

Часть III. Стандартная библиотека

template <class Op. class T>

binderlst<0p> bindlst(const 0p& op, const T& x);

Здесь Op — тип функционального объекта, Т — тип привязываемого значения.

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

#include <iostream> #include functional> #include <algorithm> using namespace std; int main(){

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

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

return 0;

} В этой программе для подсчета количества элементов применяется алгоритм стандартной библиотеки count_if (см. с. 345). Для его использования требуется подключить заголовочный файл functional>. Первыми двумя параметрами countif должны быть итераторы, определяющие начало и конец обрабатываемой последовательности. В качестве итераторов массива используются указатели на его элементы. Третий параметр функции counti f должен быть бинарной функцией или функциональным объектом. Функция bind2nd превращает условие сравнения х < у в условие х < 40.

Адаптеры указателей на функции

Для того чтобы применять связыватели к обычным указателям на функции, требуются специальные преобразователи, или адаптеры. Стандартная библиотека определяет два функциональных объекта — указатель на унарную функцию pointer_to_unary function и указатель на бинарную функцию pointer_to_binary_ function, а также две функции-адаптера ptrfun с одним и двумя аргументами, которые преобразуют переданный им в качестве параметра указатель на функцию в функциональный объект.

Ниже приведено описание шаблона класса и функции для унарных и бинарных функций:

template <class Arg. class Result>

class pointer_to_unary_function : public unary_function<Arg. Result>{ public:

explicit pointer__to_unary_function(Result (*f)(Arg)); Result operator()(Arg x) const; // Возвращает f(x)

}: template <class Arg. class Result>

pointer_to_unary_function<Arg. Result> ptr_fun(Result (*f)(Arg)); template <class Argl. class Arg2. class Result>