Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка ПИ_ИКТ Программирование по С++ (1 семестр) _Хотов.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
5.83 Mб
Скачать

Содержание отчета

  1. Титульный лист.

  2. Наименование и цель работы.

  3. Краткое теоретическое описание.

  4. Задание на лабораторную работу.

  5. Листинг программы.

  6. Результаты выполнения программы.

    1. Boost::bind (на самостоятельное изучение) Использование с глобальной функцией

Предположим, что есть функция:

bool compare(int a, int b) {return a < b;}

для того, чтобы использовать эту функцию в, например, алгоритме sort нам необходимо написать:

std::vector<int> vec(…);

std::sort(vec.begin(), vec.end(), compare);

Теперь немного усложним задачу – в зависимости от флага нам необходимо сортировать либо по возрастанию, либо по убыванию. При использовании только STL пришлось бы писать две функции. Накладно. С помощью boost эту задачу решить значительно проще:

bool compare(int a, int b, bool reverseSort) {return reverseSort ? a > b : a < b;}

std::vector<int> vec(…);

std::sort(vec.begin(), vec.end(), boost::bind(compare, _1, _2, order));

где order – булевская переменная, задающая порядок сортировки. Последняя строчка выглядит несколько странновато, но именно в ней и заключается вся суть. В результате ее компиляции будет получен код, реализующий сортировку массива, использующий для сравнения функцию compare, и передающей ей на вход три аргумента – два числа, которые необходимо сравнить, и способ их сравнения. Почему именно так? Рассмотрим этот код подробнее, записав его так:

int a = 1, b = 2;

boost::bind(compare, _1, _2, false)(a, b);

(что-то подобное содержится в недрах функции std::sort). Последняя строчка в этом коде обозначает следующее:

boost::bind – функция, создающая необходимый нам связыватель. Возвращает экземпляр функционального объекта (функтора), для которого применим оператор вызова функции. (compare, - первый аргумент функции определяет имя/указатель на функцию, которая должна быть вызвана в связывателе. В данном случае это функция compare; _1, _2 – плейсхолдеры, определяющие логику передачи параметров из оператора вызова функции в функцию compare. , false) – значение последнего аргумента, передаваемого в compare. (a, b) – оператор вызова функции, производящий связывание аргументов и вызов функции compare. В итоге будет выполнена следующий код:

compare(a, b, false);

Из приведенного примера можно увидеть, что упомянутые выше плейсхолдеры определяют связь между аргументами у оператора вызова функции связывателя и аргументами вызываемой функцией. Причем, количество аргументов у оператора вызова функции связывателя определяется количеством плейсхолдеров:

boost::bind(compare, _1, 4, false)(a, b); // неправильно.

boost::bind(compare, _1, 4, false)(a); // правильно

boost::bind(compare, _1, _2, false)(a); // неправильно

boost::bind(compare, _1, _2, false)(a, b); // правильно

Очевидно, что попытка задать в вызове boost::bind количество параметров, несоответствующее количеству обязательных параметров в вызываемой функции приведет к ошибке. Равно как и попытка указания количества параметров большего, чем количество параметров в вызываемой функции. Действуя по аналогии мы можем записать:

std::find_if(vec.begin(), vec.end(), boost::bind(compare, _1, 4, false)); // поиск первого числа, меньшего 4

std::remove_if(vec.begin(), vec.end(), boost::bind(compare, _1, 4, true)); // удаление из последовательности всех элементов, больших 4

// и т. д.

В случае использования чистого STL для каждого случая пришлось бы искать подходящий функтор… Или писать его. Здесь необходимо обратить внимание на то, что в качестве первого параметра функции bind может выступать не только указатель на функцию, но и другой функциональный объект. Например:

std::find_if(vec.begin(), vec.end(), boost::bind(std::equal_to<int>(), _1, 4));

этот строчка найдет в массиве первый элемент, равный 4.