Глава 18. Классы-контейнеры_______________________________473
template <class Arg, clas Result>
struct unary_function
{
typedef Arg argument_type;
typedef Result result_type;
};
template <class Argi, class Arg2, class Result>
struct binary_function
{
typedef Argi first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
Так же как для контейнеров и итераторов, для объектов-функций существуют адаптеры. Эти адаптеры относятся к трем базовым типам: адаптеры отрицания (negators), адаптеры связывания (binders) и адаптеры для указателей на функции. Адаптеры отрицания noti и not2 строят отрицание для функций-предикатов. Функции-предикаты — это функции, возвращающие только два значения — "истинно" или "ложно", noti принимает в качестве аргумента унарную объект-функцию (подкласс unary_function). not2 принимает бинарную объект-функцию (подкласс binary_function).
Адаптер связывания принимает в качестве аргументов бинарную функцию и некоторую величину, привязывая ее к первому или второму аргументу бинарной функции, bindlst привязывает первый аргумент и bind2nd — второй. Следующий пример использует noti и bind2nd для удаления всех целых, меньших или равных 10, из вектора целых:
vector<int>::iterator I = remove if(intVector.begin(), intVector.end(), noti(bind2nd(greater<int>(),10)));
Другой адаптер объекта-функции — ptr_fun.ptr — принимает указатель на унарную или бинарную функцию и превращает ее в объект-функцию.
Алгоритмы
Алгоритмы библиотеки STL — это функции-шаблоны параметризованные по типу итератора. Ожидаемый тип итератора указывается в объявлении функции-шаблона, как это уже обсуждалось в предыдущем разделе. Компилятор не способен проверить, соответствует ли передаваемый в качестве аргумента итератор минимально необходимой функциональности. Что произойдет если двунаправленный итератор будет передан в алгоритм sort? Следующий фрагмент определяет одну из функций sort:
template <class RandomAccessIterator> void sort(RandomAccessIterator first, RandomAccessIterator last);