Программирование >>  Разработка устойчивых систем 

1 ... 81 82 83 [ 84 ] 85 86 87 ... 196


Если вы хотите, чтобы логические данные выводились в виде значений true и false вместо 1 и О, вызовите cout.set(ios::boolalpha).

Адаптеры привязки не обязаны создавать унарный предикат] кроме того, они могут создавать любые унарные функции (то есть функции с типом возвращаемого значения, отличным от bool). Например, можно умножить каждый элемент вектора на 10, используя адаптер привязки в сочетании с алгоритмом transform():

: C06:FBinder.cpp

Адаптеры привязки не ограничиваются построением предикатов

{L} Generators

#include <algorithm>

#inc1ude <cstd1ib>

#inc1ude <ctime>

#inc1ude <functional>

#inc1ude <iostream>

#inc1ude <iterator>

#include <vector>

#include Generators.h

using namespace std;

int mainO { ostream iterator<int> outCcout. ); vector<int> v(15);

srand(time(0)); Раскрутка генератора случайных чисел generate(v.begin(), v.endO. URandGen(20)); copy(v.begin(). v.endO, out); transform(v.begin(), v.endO. v.beginO,

bind2nd(multiplies<int>(). 10)); copyCv.beginO. v.endO, out); } /;-

Третий аргумент transform() равен первому, поэтому итоговые элементы копируются обратно в исходный вектор. Объект функции, созданный адаптером bind2ncl(), в данном примере генерирует результат типа int.

Адаптер привязки не позволяет зафиксировать объект функции, однако фиксируемый аргумент не обязан быть константой времени компиляции. Пример:

: C06;BinderValue.cpp

Определение фиксируемого аргумента на стадии выполнения

#include <algorithm>

linclude <functional>

linclude <iostream>

linclude <iterator>

linclude <cstdlib>

using namespace std;

int boundedRandO { return randO 100; }

int mainO { const int SZ = 20; int a[SZ]. b[SZ] = {0}; generateCa. a + SZ. boundedRand); int val = boundedRandO; int* end = remove copy if(a. a + SZ. b.

bind2nd(greater<int>(). val)); Сортировка для упрощения просмотра; sort(a, а + SZ); sort(b. end);



ostreamJterator<int> out (cout, ): cout Original Sequence:\n : copyCa, a + SZ, out): cout endl: cout Values less <= val endl: copyCb. end, out): cout endl: } III:-

Мы заполняем массив 20 случайными числами от О до 100, после чего пользователь вводит пороговое значение в командной строке. В вызове remove copy if() фиксируемый аргумент bind2nd() представляет собой случайное число из исходного интервала. Вот как выглядит результат одного из запусков:

4 12 15 17 19 21 26 30 47 48 56 58 60 63 71 79 82 90 92 95

Values less <= 41

4 12 15 17 19 21 26 30

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

Алгоритмам, получающим функции при вызове, может передаваться как указатель на обычную функцию, так и указатель на объект функции. В первом случае алгоритм использует традиционный механизм вызова, а во втором вызывается операторная функция operator() этого объекта. Так, в примере CopyInts2.cpp в качестве предиката для вызова remove copyJf() передавалась функция gtl5(). Кроме того, указатели на функции, возвращающие случайные числа, передавались алгоритмам generateO и generate n().

Однако простые функции не могут использоваться с адаптерами объектов функций (такими, как bind2nd()), поскольку последние предполагают существование определений типов для аргументов и возвращаемого значения. Но вам не придется вручную преобразовывать функции в объекты функций - в стандартной библиотеке предусмотрены адаптеры для выполнения этой работы. Адаптер ptr fun() получает указатель на функцию и преобразует его в объект функции. Он не рассчитан на работу с функциями без аргументов и может использоваться только с унарными и бинарными функциями.

В следующей программе адаптер ptr fun() преобразует унарную функцию в объект функции:

: C06:PtrFunl.cpp

Использование ptr fun() с унарной функцией

linclude <algorithm>

linclude <cmath>

linclude <functional>

linclude <iostream>

linclude <iterator>

linclude <vector>

using namespace std:

int d[] = { 123. 94, 10, 314. 315 }: const int DSZ = sizeof d / sizeof *d: bool isEven(int x) { return x 2 == 0: }

int mainO { vector<bool> vb:

transformed, d + DSZ. back inserter(vb),

notl(ptr fun(isEven))): copyCvb.beginO. vb.endO.



ostreamjterator<bool>(cout. )): cout end!: Результат: 10 0 0 1 } /:-

Мы не можем просто передать адаптеру notl функцию isEven, потому что адаптеру необходимо знать фактический тип аргумента и возвращаемого значения. Адаптер ptr fun() определяет эти типы по аргументам шаблона. Определение унарной версии ptr fun() выглядит примерно так:

template <class Arg. class Result> pointer to unary function<Arg. Result> ptr fun(Result (*fptr)(Arg)) { return pointer to unary function<Arg. Result>(fptr):

Как видите, эта версия ptr fun() определяет типы аргумента и результата по fptr и использует их для инициализации объекта pointer to unary function, в котором хранится fptr. Оператор вызова функции объекта pointer to unary function просто вызывает fptr в последней строке своей реализации:

template <class Arg, class Result>

class pointer to unary function

: public unary function<Arg. Result> {

Result (*fptr)(Arg): Сохраняет указатель на функцию public:

pointer to unary function(Result (*x)(Arg)) : fptr(x) {} Result operatorO(Arg x) const { return fptr(x): }

Поскольку объект pointer to unary function объявлен производным от una-ry function, унаследованные определения типов становятся доступными для адаптера notl.

Также существует бинарная версия ptr fun(), которая возвращает объект pointer to binary function (производный от binary function). Этот объект ведет себя так же, как его унарный аналог. В следующей программе бинарная версия ptr fun() используется для возведения элементов числового интервала в степень. Кроме того, этот пример демонстрирует потенциальную проблему с передачей адаптеру ptr fun() перегруженных функций.

: C06:PtrFun2.cpp

Использование ptr fun() с бинарными функциями

#include <algorithm>

linclude <cmath>

linclude <functional>

linclude <iostream>

linclude <iterator>

linclude <vector>

using namespace std:

double d[] = { 01.23. 91.370. 56.661.

023.230. 19.959. 1.0. 3.14159 }: const int DSZ = sizeof d / sizeof *d:

int mainO { vector<double> vd:

transform(d. d + DSZ. back inserter(vd). bind2nd(ptr fun<double. double, double>(pow). 2.0)):



1 ... 81 82 83 [ 84 ] 85 86 87 ... 196

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