14.8.2. Библиотечные объекты функций
Стандартная библиотека определяет набор классов, представляющих арифметические, реляционные и логические операторы. Каждый класс определяет оператор вызова, который применяет одноименный оператор. Например, у класса plus есть оператор вызова функции, который применяет оператор + к паре операндов; класс modulus определяет оператор вызова, применяющий бинарный оператор %; класс equal_to применяет оператор ==; и т.д.
Эти классы являются шаблонами, которым передается один тип. Он определяет тип параметра оператора вызова. Например, класс plus<string> применяет строковый оператор суммы к объектам класса string; у класса plus<int> типом операндов будет int; класс plus<Sales_data> применяет оператор + к объектам класса Sales_data; и т.д.:
plus<int> intAdd; // объект функции, способный сложить
// два значения типа int
negate<int> intNegate; // объект функции, способный изменить знак
// значения типа int
// использование оператора intAdd::operator(int, int) для
// сложения чисел 10 и 20
int sum = intAdd(10, 20); // эквивалент sum = 30
sum = intNegate(intAdd(10, 20)); // эквивалент sum = 30
// использование оператора intNegate::operator(int) для создания
// числа -10 как второго параметра выражения intAdd::operator(int, int)
sum = intAdd(10, intNegate(10)); // sum = 0
Эти типы, перечислены в табл. 4.2, определены в заголовке functional.
Таблица 14.2. Библиотечные объекты функций
Арифметические Реляционные Логические plus<Type> equal_to<Type> logical_and<Type> minus<Type> not_equal_to<Type> logical_or<Type> multiplies<Type> greater<Type> logical_not<Type> divides<Type> greater_equal<Type> modulus<Type> less<Type> negate<Type> less_equal<Type>Применение библиотечного объекта функции с алгоритмами
Классы объектов функций, представляющие операторы, зачастую используются для переопределения заданного по умолчанию оператора, используемого алгоритмом. Как уже упоминалось, по умолчанию алгоритмы сортировки используют оператор operator< для сортировки последовательности в порядке возрастания. Для сортировки в порядке убывания можно передать объект типа greater. Этот класс создает оператор вызова, который вызывает оператор "больше" основного типа элемента. Предположим, например, что svec — это вектор типа vector<string>:
// передает временный объект функции, который применяет
// оператор > к двум строкам
sort(svec.begin(), svec.end(), greater<string>());
Это сортирует вектор в порядке убывания. Третий аргумент — безымянный объект типа greater<string>. Когда функция sort() сравнит элементы, вместо оператора < типа элемента она применит переданный объект функции greater. Этот объект применит оператор > к элементам типа string.
Одним из важнейших аспектов этих библиотечных объектов функций является то, что библиотека гарантирует их работоспособность с указателями. Помните, что результат сравнения двух несвязанных указателей непредсказуем (см. раздел 3.5.3). Но может понадобиться сортировать вектор указателей на основании их адреса в памяти. Хотя сделать это самостоятельно непросто, вполне можно применить один из библиотечных объектов функции:
vector<string *> nameTable; // вектор указателей
// ошибка: указатели в nameTable не связаны, результат < непредсказуем
sort(nameTable.begin(), nameTable.end(),
[](string *a, string *b) { return a < b; });
// ok: библиотека гарантирует, что less для типов указателя определен
sort(nameTable.begin(), nameTable.end(), less<string*>());
Стоит также обратить внимание на то, что ассоциативные контейнеры используют для упорядочивания своих элементов объект типа less<key_type>. В результате можно определить набор (set) указателей или использовать указатель как ключ в карте (map) без необходимости определять тип less самостоятельно.
Упражнения раздела 14.8.2
Упражнение 14.42. Используя библиотечные объекты и адаптеры функций, определите объекты для:
(a) Подсчета количеств значений больше 1024
(b) Поиска первой строки, не равной pooh
(c) Умножения всех значений на 2
Упражнение 14.43. Используя библиотечные объекты функций, определите, делимо ли переданное значение типа int на некий элемент в контейнере целых чисел.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОК