Функторы

Функтор — это класс, в котором определен «операторный» метод 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; }
};

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов