Адаптеры

Адаптеры преобразуют указатели на функции и методы класса таким образом, чтобы обычные функции и методы класса можно было передавать вместо функторов. Перечислим адаптеры, доступные в STL:

  • ptr_fun — преобразует указатель на функцию. Синтаксис:
ptr_fun(Название_функции)

В параметре Название_функции можно передать название функции, принимающей один или два параметра. Адаптер возвращает экземпляры классов pointer_to_unary_function или pointer_to_binary_function в зависимости от количества параметров функции. Пример передачи адреса функции с одним и двумя параметрами:

bool func1(int x) {
   return x < 0;
}
bool func2(int x, int y) {
   return x < y;
}
// ... Фрагмент опущен ...
std::cout << std::boolalpha << std::ptr_fun(func1)(-1);
// true ( вызов func1(-1) )
std::cout << std::boolalpha
          << std::bind2nd(std::ptr_fun(func2), 4)(5);
// false ( вызов func2(5, 4) )

Начиная со стандарта C++11, вместо адаптера ptr_fun лучше использовать класс function (см. разд. 12.12.2):

std::function<bool(int)> f1 = func1;
std::function<bool(int, int)> f2 = func2;
std::cout << std::boolalpha << f1(-1);
// true ( вызов func1(-1) )
std::cout << std::boolalpha
          << std::bind2nd(f2, 4)(5);
// false ( вызов func2(5, 4) )
  • mem_fun — позволяет использовать метод класса при хранении в контейнере указателей на экземпляры класса. Пример передачи адреса метода print() класса C в алгоритм for_each, который осуществляет перебор элементов контейнера:
void C::print() {
   std::cout << x_ << " ";
}
// ... Фрагмент опущен ...
std::vector<C *> arr2;
// ... Фрагмент опущен ...
std::for_each( arr2.begin(), arr2.end(),
               std::mem_fun(&C::print) );
  • mem_fun_ref — позволяет использовать метод класса при хранении в контейнере объектов класса. Пример:
std::vector<C> arr1;
// ... Фрагмент опущен ...
std::for_each( arr1.begin(), arr1.end(),
               std::mem_fun_ref(&C::print) );

Начиная со стандарта C++11, вместо адаптеров mem_fun и mem_fun_ref лучше использовать адаптер mem_fn, который можно применять и для указателей на экземпляры класса, и для объектов.

Пример использования адаптеров mem_fun, mem_fun_ref и mem_fn приведен в листинге 16.3.

Листинг 16.3. Пример использования адаптеров mem_fun, mem_fun_ref и mem_fn

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>

class C {
   int x_;
public:
   C() { x_ = 0; }
   C(int x) { x_ = x; }
   C(const C &obj) { x_ = obj.x_; }
   void print();
   void plus(int x);
};

void C::print() {
   std::cout << x_ << " ";
}
void C::plus(int x) {
   x_ += x;
}

int main() {
   std::vector<C> arr1;   // Хранит объекты класса C
   std::vector<C *> arr2; // Хранит указатели на объекты
   C obj1(40);
   C obj2(50);
   C obj3(60);

   // Использование адаптера mem_fun_ref
   arr1.push_back(C(10));
   arr1.push_back(C(20));
   arr1.push_back(C(30));
   std::for_each( arr1.begin(), arr1.end(),
                  std::mem_fun_ref(&C::print) );
   std::cout << std::endl; // 10 20 30
   // Изменяем значение каждого объекта
   std::for_each( arr1.begin(), arr1.end(),
           std::bind2nd(std::mem_fun_ref(&C::plus), 5) );
   std::for_each( arr1.begin(), arr1.end(),
                  std::mem_fun_ref(&C::print) );
   std::cout << std::endl; // 15 25 35

   // Использование адаптера mem_fun
   arr2.push_back(&obj1);
   arr2.push_back(&obj2);
   arr2.push_back(&obj3);
   std::for_each( arr2.begin(), arr2.end(),
                  std::mem_fun(&C::print) );
   std::cout << std::endl; // 40 50 60

   // Использование адаптера mem_fn
   std::for_each( arr1.begin(), arr1.end(),
                  std::mem_fn(&C::print) );
   std::cout << std::endl; // 15 25 35
   std::for_each( arr2.begin(), arr2.end(),
                  std::mem_fn(&C::print) );
   std::cout << std::endl; // 40 50 60
   return 0;
}

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

Помощь сайту

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

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