Редакторы связей

Редакторы связей позволяют указать конкретное значение в одном из параметров бинарного функтора, создавая таким образом унарный функтор. Существуют два редактора связей (объявлены устаревшими в стандарте C++11):

  • bind1st — передает Значение1 в первый параметр функтора Функтор, а Значение2 во второй параметр функтора Функтор:
bind1st(Функтор, Значение1)(Значение2)

Эквивалентно:

Функтор(Значение1, Значение2)

Пример:

std::cout << std::boolalpha
          << std::bind1st(std::less<int>(), 4)(5);
// true (4 < 5)
  • bind2nd — передает Значение1 во второй параметр функтора Функтор, а Значение2 в первый параметр функтора Функтор:
bind2nd(Функтор, Значение1)(Значение2)

Эквивалентно:

Функтор(Значение2, Значение1)

Пример:

std::cout << std::boolalpha
          << std::bind2nd(std::less<int>(), 4)(5);
// false (5 < 4)

Наиболее часто редакторы связей применяются совместно с алгоритмами. В качестве примера найдем первый элемент динамического массива, который имеет значение больше 4, с помощью алгоритма find_if (листинг 16.4). Более подробно алгоритмы будут рассматриваться в главе 19.

Листинг 16.4. Пример использования редакторов связей

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

int main() {
   std::vector<int> arr;
   std::vector<int>::iterator it;
   for (int i = 1; i <= 10; ++i) arr.push_back(i);
   // arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
   it = std::find_if(arr.begin(), arr.end(),
                     std::bind2nd(std::greater<int>(), 4));
   if ( it == arr.end() )
      std::cout << "No" << std::endl;
   else
      std::cout << *it << std::endl;   // 5
   return 0;
}

Начиная со стандарта C++11, вместо функтора можно указать лямбда-выражение:

it = std::find_if(arr.begin(), arr.end(),
                  [](int a) { return a > 4; } );

Посмотрите, насколько проще и понятнее выглядит эта инструкция.

Функция bind(), добавленная стандартом С++11, позволяет связать пользовательскую функцию или метод класса со значениями параметров. В качестве примера создадим функцию, принимающую два параметра и возвращающую результат сложения:

int sum(int x, int y) {
   return x + y;
}

Свяжем функцию sum() со значениями 5 и 2, а затем вызовем функцию:

// #include <functional>
auto f1 = std::bind(sum, 5, 2);
std::cout << f1() << std::endl;      // 7

Вместо определенных значений можно указать заполнители _1, _2, ..., _N, объявленные в пространстве имен placeholders. При вызове функции вместо этих заполнителей будут подставлены значения, указанные внутри круглых скобок. Число после подчеркивания означает номер параметра:

using namespace std::placeholders;
auto f2 = std::bind(sum, _1, _2);
std::cout << f2(5, 3) << std::endl;  // 8

В этом примере вместо _1 будет подставлено число 5, а вместо _2 — число 3.

Можно выполнить связывание с методом класса. Например, свяжем метод plus() класса C (см. листинг 16.3) с объектом и значением 3:

using namespace std::placeholders;
auto f3 = std::bind(&C::plus, _1, _2);
C obj(5);
f3(obj, 3);
obj.print(); // 8

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

Помощь сайту

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

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