Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
###Cpp_лкц1_1.09_11_#дляБАК#29_01_12.doc
Скачиваний:
40
Добавлен:
29.04.2019
Размер:
6.42 Mб
Скачать

Глава 13. Итераторы и функциональные объекты

341

m.push_back(monstr("vasia"));

m.push_back(monstr(red));

cout « " M0N5TRY:" « endl;

for (int i = 0; i<m.size(); i++) cout « m[i] « " ";

cout « endl;

cout « " C0UNT_IF: ";

cout « count_if(m.begin(), m.endO,

bind2nd(ptr_fun(less_health). 20)); return 0;

}

Булева функция lessjiealth сравнивает поля health у двух переданных ей аргументов класса monstr. Чтобы сравнить поле health с константой, требуется связать с ней второй аргумент этой функции. Связыватель bi nd2nd должен получать в качестве первого аргумента функциональный объект, который формируется с помощью адаптера ptr_fun. Результат работы программы (больных монстров — 2 штуки):

M0NSTRY:

monstr: ammo = 30 health = 10

monstr: ammo = 10 health = 200

monstr: ammo = 10 health = 1

COUNTJF: 2

Адаптеры методов

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

#include <iostream>

#include <algorithm>

using namespace std:

void show(int a){ cout « a « endl;}

int main(){

int m[4] = {3, 5. 9. 6};

for_each(m, m + 4. show);

• return 0;

}

Если вместо обычного массива использовать контейнер, содержащий объекты некоторого класса, то записать в аналогичной программе на месте функции show вызов метода класса не удастся, поскольку метод требуется вызывать с указанием конкретного объекта класса.

Адаптеры методов позволяют использовать методы классов в качестве аргументов стандартных алгоритмов. Адаптер метода так же, как отрицатель и связыва-

342

Часть III. Стандартная библиотека

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

Таблица 13.4. Адаптеры методов классов

Имя

Тип объекта

Действие

■ mem fun

mem fun t

Вызывает безаргументный метод через указатель

mem fun

const mem fun t

Вызывает безаргументный константный метод через указатель

i mem_fun

mem_funl_t

Вызывает унарный метод через указатель

mem_fun_ref

mem_fun_ref _t

Вызывает безаргументный метод через ссылку

mem_fun_ref

const_mem_fun_ref _t

Вызывает безаргументный константный метод через ссылку

mem_fun_ref

mem_funl_ref _t

Вызывает унарный метод через ссылку

mem_fun_ref

const_mem_funl_ref _t

Вызывает унарный константный метод через ссылку

mem_fun_ref

const_mem_funl_t

Вызывает унарный константный метод через указатель

В качестве примера опишем в классе monstr метод dead, определяющий, жив ли монстр:

bool dead(){return ihealth;} Подсчитать с помощью уже упоминавшегося алгоритма count_i f количество потерь в векторе, описанном, например, как

vector <monstr> ostrich (100);

можно с помощью оператора:

cout « count_if(ostrich.begiл(). ostrich.end(), mem fun ref(&monstr::dead));