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

12.3.1. Предопределенные объекты-функции

Предопределенные объекты-функции подразделяются на арифметические, логические и сравнительные. Каждый объект – это шаблон класса, параметризованный типами операндов. Для использования любого из них необходимо включить заголовочный файл:

#include <functional>

Например, объект-функция, поддерживающий сложение, – это шаблон класса с именем plus. Для определения экземпляра, способного складывать два целых числа, нужно написать:

#include <functional>


plus< int > intAdd;

Для выполнения операции сложения мы применяем перегруженный оператор вызова к intAdd точно так же, как и к классу AddImage в предыдущем разделе:

int ival1 = 10, ival2 = 20;

// эквивалентно int sum = ival1 + ival2;


int sum = intAdd( ival1, ival2 );

Реализация шаблона класса plus вызывает оператор сложения, ассоциированный с типом своего параметра – int. Этот и другие предопределенные объекты-функции применяются прежде всего в качестве аргументов обобщенных алгоритмов и обычно замещают подразумеваемую по умолчанию операцию. Например, по умолчанию алгоритм sort() располагает элементы контейнера в порядке возрастания с помощью оператора “меньше” базового типа. Для сортировки по убыванию мы передаем предопределенный шаблон класса greater, который вызывает оператор “больше”:

vector< string > svec;

// ...


sort( svec.begin(), svec.end(), greater<string>() );

Предопределенные объекты-функции перечислены в следующих разделах и разбиты на категории: арифметические, логические и сравнительные. Применение каждого из них иллюстрируется как в качестве именованного, так и в качестве безымянного объекта, передаваемого функции. Мы пользуемся следующими определениями объектов, включая и определение простого класса (перегрузка операторов подробно рассматривается в главе 15):

class Int {

public:

Int( int ival = 0 ) : _val( ival ) {}

int operator-() { return -_val; }

int operator%(int ival) { return -_val % ival; }

bool operator<(int ival) { return -_val < ival; }

bool operator!() { return -_val == 0; }

private:

int _val;

};

vector< string > svec;

string sval1, sval2, sres;

complex cval1, cval2, cres;

int ival1, ival2, ires;

Int Ival1, Ival2, Ires;


double dval1, dval2, dres;

Кроме того, мы определяем два шаблона функций, которым передаем различные безымянные объекты-функции:

template <class FuncObject, class Type>

Type UnaryFunc( FuncObject fob, const Type &val )

{ return fob( val ); }

template <class FuncObject, class Type>

Type BinaryFunc( FuncObject fob,

const Type &val1, const Type &val2 )


{ return fob( val1, val2 ); }

12.3.2. Арифметические объекты-функции

Предопределенные арифметические объекты-функции поддерживают операции сложения, вычитания, умножения, деления, взятия остатка и вычисления противоположного по знаку значения. Вызываемый оператор – это экземпляр, ассоциированный с типом Type. Если тип является классом, предоставляющим перегруженную реализацию оператора, то именно эта реализация и вызывается.

  • Сложение: plus<Type>

plus<string> stringAdd;

// вызывается string::operator+()

sres = stringAdd( sval1, sval2 );


dres = BinaryFunc( plus<double>(), dval1, dval2 );

  • Вычитание: minus<Type>

minus<int> intSub;

ires = intSub( ival1, ival2 );


dres = BinaryFunc( minus<double>(), dval1, dval2 );

  • Умножение: multiplies<Type>

multiplies<complex> complexMultiplies;

cres = complexMultiplies( cval1, cval2 );


dres = BinaryFunc( multiplies<double>(), dval1, dval2 );

  • Деление: divides<Type>

divides<int> intDivides;

ires = intDivides( ival1, ival2 );


dres = BinaryFunc( divides<double>(), dval1, dval2 );

  • Взятие остатка: modulus<Type>

modulus<Int> IntModulus;

Ires = IntModulus( Ival1, Ival2 );


ires = BinaryFunc( modulus<int>(), ival1, ival2 );

  • Вычисление противоположного значения: negate<Type>

negate<int> intNegate;

ires = intNegate( ires );


Ires = UnaryFunc( negate<Int>(), Ival1 );