Этот сайт использует cookies. Продолжение работы с сайтом означает, что Вы согласны!
Функторы
Функтор — это класс, в котором определен «операторный» метод operator()()
. В этом случае можно обработать вызов экземпляра класса как вызов функции. Пример перегрузки оператора ()
приведен в листинге 16.2.
Листинг 16.2. Перегрузка оператора ()
#include <iostream>
class C {
int x_;
public:
C() { x_ = 0; }
void operator()(int x) { x_ = x; }
int operator()() { return x_; }
};
int main() {
C obj;
obj(10);
std::cout << obj() << std::endl; // 10
std::cout << C()() << std::endl; // 0
return 0;
}
В STL имеется множество встроенных функторов, определенных в заголовочном файле functional
:
#include <functional>
Встроенные функторы делятся на унарные и бинарные. Унарные функторы принимают один параметр. Перечислим унарные функторы:
negate
— унарный минус:
std::cout << std::negate<int>()(10); // -10
logical_not
— логическое отрицание:
std::cout << std::boolalpha
<< std::logical_not<bool>()(false); // true
Бинарные функторы принимают два параметра. Перечислим бинарные функторы:
plus
— оператор сложения+
:
std::cout << std::plus<int>()(5, 3); // 8
minus
— оператор вычитания-
:
std::cout << std::minus<int>()(5, 3); // 2
multiplies
— оператор умножения*
:
std::cout << std::multiplies<int>()(5, 3); // 15
divides
— оператор деления/
:
std::cout << std::divides<int>()(15, 3); // 5
modulus
— остаток от деления%
:
std::cout << std::modulus<int>()(10, 3); // 1
bit_and
— двоичноеИ
&
:
std::cout << std::bit_and<int>()(100, 75); // 64
bit_or
— двоичноеИЛИ
|
:
std::cout << std::bit_or<int>()(100, 75); // 111
bit_xor
— двоичное исключающееИЛИ
^
:
std::cout << std::bit_xor<int>()(100, 250); // 158
equal_to
— оператор равно==
:
std::cout << std::boolalpha
<< std::equal_to<int>()(4, 5); // false
not_equal_to
— оператор!=
:
std::cout << std::boolalpha
<< std::not_equal_to<int>()(4, 5); // true
less
— оператор меньше<
:
std::cout << std::boolalpha
<< std::less<int>()(4, 5); // true
less_equal
— оператор меньше или равно<=
:
std::cout << std::boolalpha
<< std::less_equal<int>()(5, 5); // true
greater
— оператор больше>
:
std::cout << std::boolalpha
<< std::greater<int>()(4, 5); // false
greater_equal
— оператор больше или равно>=
:
std::cout << std::boolalpha
<< std::greater_equal<int>()(5, 5); // true
logical_and
— логический оператор&&
:
std::cout << std::boolalpha
<< std::logical_and<bool>()(false, true); // false
logical_or
— логический оператор||
:
std::cout << std::boolalpha
<< std::logical_or<bool>()(false, true); // true
Как видно из примеров, создание объекта производится по следующей схеме:
Название_функтора<Тип>()
Тип данных должен совпадать с типом данных контейнера. В качестве типа может выступать объект пользовательского класса. В этом случае внутри класса необходимо перегрузить оператор, соответствующий функтору. Например, при использовании функтора less
внутри класса должен быть метод operator<()
, принимающий в качестве параметра ссылку на экземпляр того же класса, или соответствующая дружественная функция.
Чтобы вызвать функтор необходимо добавить круглые скобки, внутри которых передать один или два параметра:
Название_функтора<Тип>()(Параметры)
До выхода стандарта C++11, пользовательские классы функторов должны были наследовать класс unary_function
(для унарных функторов) или binary_function
(для бинарных функторов). Стандарт C++11 объявил эти классы устаревшими. Объявление класса unary_function
:
template<typename _Arg, typename _Result>
struct unary_function {
typedef _Arg argument_type;
typedef _Result result_type;
};
Объявление класса binary_function
:
template<typename _Arg1, typename _Arg2, typename _Result>
struct binary_function {
typedef _Arg1 first_argument_type;
typedef _Arg2 second_argument_type;
typedef _Result result_type;
};
Например, реализация функтора less
выглядит следующим образом:
template<typename _Tp>
struct less : public binary_function<_Tp, _Tp, bool> {
bool operator()(const _Tp &__x, const _Tp &__y) const
{ return __x < __y; }
};
Помощь сайту
ЮMoney (Yandex-деньги): 410011140483022
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов