Программирование >>  Операторы преобразования типа 

1 ... 95 96 97 [ 98 ] 99 100 101 ... 239


Вторая форма используется в ситуации, когда глобальная функция вызывается с двумя параметрами, а вам, например, она нужна как унарная функция:

Поиск первой непустой строки

pos = find 1f (coll.beginO. coll.endO, Интервал

b1nd2nd(ptr fun(strcmp), )): Критерий поиска

В этом фрагменте функция strcmp() языка С сравнивает каждый элемент с пустой строкой языка С. Если строки совпадают, функция strcmp() возвращает О (эквивалент false). Таким образом, данный вызов frnd rf() возвращает позицию первого элемента, отличного от пустой строки. Другой пример использования функционального адаптера ptr fun приведен на с. 318.

Написание пользовательских объектов функций для функциональных адаптеров

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

template <class Arg. class Result> struct unary funct1on (

typedef Arg argument type;

typedef Result result type:

template <class Argl. class Arg2. class Result> struct binary funct1on {

typedef Argl f1rst argument type:

typedef Arg2 second arguiTtent type;

typedef Result result type;

Объявляя свой объект функции производным от одного из этих типов, вы легко обеспечиваете соблюдение этих требований и объект функции становится совместимым с адаптерами*.

В следующем примере приведено полное определение объекта функции для возведения первого аргумента в степень, заданную вторым аргументом:

fo/fopow.hpp Include <funct1onal> Iinclude <cmath>

template <class Tl, class T2>

struct fopow : public std::b1nary funct1on<Tl. T2. Tl>

Tl OperatorO (Tl base. T2 exp) const ( return std::pow(base.exp);



Первый аргумент и возвращаемое значение относятся к одному типу Т1, а показатель степени может относиться к другому типу 12, Передавая эту информацию binary function, мы обеспечиваем определение необходимых типов. Тем пе менее вместо использования binary function типы можно определить напрямую. Как обычно бывает в STL, функциональные адаптеры соответствуют концепции чистой абстракции: любой объект, который ведет себя как объект функции, совместимый с функциональными адаптерами, является таковым. ;

Следующая программа показывает, как работать с пользовательским объектом функции fopow. В частности, продемонстрировано использование fbpow с адаптерами bindlst и bind2nd:

fo/fopowl.cpp #lnclude <iostream> #inclLide <vector> #lnclude <algorlthm> using namespace std:

Включение пользовательского обьекта функции fopow<> #lnc1ude fopow.hpp

int mainO (

vector<int> col 1:

Вставка элементов со значениями от 1 до 9 for Cint i=l: i<=9: ++i) { coll.push backCi):

Вывод числа 3. возведенного в степень каждого элемента transform (coll.beginC). coll.endO. . Источник

ostream iterator<int>(cout. ). Приемник

bindlstCfopow<float.1nt>().3)): Операция cout endl:

Вывод всех элементов, возведенных в степень 3 transform (coll .beginO, coll.endO. Источник

ostream 1terator<int>(cout. ). Приемник

bind2nd(fopow<float,int>(),3)): Операция cout endl:

Программа выводит следующий результат:

3 9 27 81 243 729 2187 6561 19683 1 8 27 64 125 216 343 512 729

Обратите внимание: объект функции fopow реализован для типов float и int Если использовать int как для основания, так и для показателя степени, вы сможете вызвать pow() с двумя аргументами типа int, но при этом будет нарушена



переносимость кода, поскольку в соответствии со стандартом функция pow() перегружается более чем для одного, но не для всех базовых типов:

transform (соП . begin(). coll.endO.

ostream iterator<int>(cout. ).

b1ndlstCfopow<1nt,int>0.3)): ОШИБКА: неоднозначность Более подробное описание этой проблемы приводится на с. 557.

Дополнительные композиционные адаптеры

Возможность объединения объектов функций играет важную роль в построении программного кода из готовых компонентов. Композиция позволяет конструировать очень сложные объекты функций из более простых частей. Конечно, было бы очень полезно, чтобы практически любое функциональное отношение представлялось в виде комбинации объектов функций, К сожалению, набор адаптеров в стандартной библиотеке С++ недостаточно широк. Например, не существует адаптера, которой бы позволял объединить две унарные операции для формулировки критерия вида одно и другое .

Теоретически в библиотеке пригодились бы следующие композиционные адаптеры.

О f(g(e/m)). Общая форма унарной композиции - вложенные вызовы унарных предикатов, при которых результаты вызова предиката д() являются входными данными для предиката f(). Все выражение работает как унарный предикат.

О f{g{elem1 ,elem2)). Два элемента elemi и elem2 передаются в аргументах бинарного предиката д(), а результать!, как и в предыдущем случае, являются входными данными для унарного предиката f(). Все выражение работает как бинарный предикат.

О f{g{elem),h{elem)). Элемент elem передается двум разным унарным предикатам д() и h(), а результаты обрабатываются бинарным предикатом f(). Все выражение работает как унарный предикат.

О f{g{elem1),h{elem2)). В этой форме два элемента elemi и elem2 передаются двум разным унарным предикатам д() и h(), а результаты обрабатываются бинарным предикатом fO. Все выражение работает как бинарный предикат.

К сожалению, эти композиционные адаптеры не были стандартизированы, поэтому для них не существуют стандартных имен. В реализации STL от SGI были определены имена для двух из перечисленных адаптеров, однако сообщество программистов еще не выбрало наиболее подходящие. В табл. 8.5 приведены имена, которые мы будем использовать в этой книге.

В архиве библиотек С++ Boost (http: wvvw.boost.org) можно найти как имена, которые должны использоваться в будущем, так и их полную реализацию. Ниже описаны три адаптера, которые часто встречаются в книге.



1 ... 95 96 97 [ 98 ] 99 100 101 ... 239

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика