Поиск первого объекта, который удовлетворяет
условию, заданному предикатом, осуществляется с
помощью шаблона функции f ind_if. В качестве
третьего, параметра она требует задать имя
функции-предиката. Введите в состав класса
объявление такой функции:
//=========
Предикат принадлежности к teenager
friend bool
Teen (Man& m);
Тело этой функции определите глобально, то есть
вне класса:
//=========
Предикат принадлежности к teenager
bool
Teen(Man& m)
{
return
13 < m.m_Age && m.m_Age < 19;
}
Теперь покажем, как искать в контейнере первый
элемент, удовлетворяющий предикату, а также все
элементы, удовлетворяющие этому условию. Ниже
нам понадобятся несколько объектов класса Man,
поэтому мы ввели их объявление в начало функции
main. Далее везде мы будем считать, что эти
объекты присутствуют в функции main, но не будем
приводить их заново:
void
main ()
{
//======== Набор объектов класса Man
Man joe("Joe Doe",30),
joy ("Joy Amore", 18) ,
Mаrу("Mary
Poppins",36),
duke("Duke Ellington",90),
liza("Liza Dale", 17),
simon("Simon Paul",15),
zoran("Zoran Todorovitch",27) ,
Charlie("Charlie Parker",60),
win("Winton Kelly",50),
mela("Melissa Robinson",9);
vector<Man> men;
men.push_back (zoran);
men.push_back (liza);
men.push_back (simon);
men.push_back (mela);
// Поиск первого объекта, удовлетворяющего
предикату
vector<Man>::iterator p =
find_if (men .begin () ,
men.endO, Teen);
//======== Ручной поиск всех таких объектов
while
(p != men.end())
{
cout
« "\nTeen: " « *p;
p = find_if(++p, men.endO, Teen);
}
cout
« "\nNo more Teens\n";
//========
Подсчет всех
teenagers
uint teen = count_if (men.begin (),men.endO ,
Teen);
cout
« "\n\n Teen totals: " « teen;
//========
Выполняем функцию для всех объектов
for_each(men.begin(),men.end(),OutTeen) ;
//======== Используем обратный итератор
cout«"\n\nMan
in reverse\n";
for
(vector<Man>::reverse_iterator
r = men.rbegin();
r != men.rendO; r++) cout«*r«";
//======== Заполняем вектор целых
vector<int> v;
for
(int i=l; i<4; i++) v.push_back(i);
//========
Иллюстрируем алгоритм и адаптивный
functor
transform(v.begin () , v.end(), v.begin (),
negate<int> () ) ;
pr(v,"Integer Negation");
//======== Создаем еще два вектора целых
vector<int> vl(v.size()), v2 (v.size());
//======== Иллюстрируем алгоритм заполнения
вектора
fill (vl.begin (), vl.endO, 100);
//======== Иллюстрируем проверку
assert (vl .size () >= v.size() && v2.size() >=
v.sizeO);
//======== Иллюстрируем вторую версию transform
transform(v.begin(), v.end(), vl.begin(),
v2.begin(),
plus<int>() ) ;
pr(v2,"Plus");
cout
« "\n\n";
}
В рассмотренном фрагменте мы иллюстрируем
использование алгоритма count_if, который
проходит по заданному диапазону
последовательности и возвращает количество
объектов, удовлетворяющих предикату. Алгоритм f
or_each позволяет выполнить определенное
действие для заданного диапазона
последовательности. В примере функция OutTeen
вызывается для всех элементов контейнера.
Приведем тело этой функции:
void
OutTeen(Man& m)
{
// Если парамтр удовлетворяет предикату, то
выводим его
if
(Teen(m))
cout
« "\nTeen: " « m;
}
Далее в коде демонстрируется, как использовать
обратный итератор reverse_ iterator. Для него
справедливы позиции rbegin — последний элемент
последовательности и rend — барьер,
ограничивающий последовательность спереди.
Операция ++ сдвигает итератор на один элемент в
сторону к началу последовательности.
Последний фрагмент функции main демонстрирует
использование алгоритма transform, который
воздействует на каждый элемент указанного
диапазона и модифицирует его в соответствии либо
с unary function (первая версия), либо с binary
function (вторая версия). Суть модификации
определяется последним параметром. В нашем
случае мы используем negator (отрицатель) и
бинарную операцию plus, настроенную на тип int.
Сложить два контейнера можно и другими
способами.
Если вы подключите файл заголовков <assert. h>,
то сможете осуществлять логические проверки с
помощью функции assert. Она проверяет свой
аргумент и, если он равен false, выводит на
экран сообщение вида:
Assertion failed: s.topQ == joy,
file C:\My ProjectsXStack.cpp, line 29
abnormal program termination
Затем прекращает процесс вызовом функции
abort.
Если результатом выражения (аргумента функции
assert) будет true, то выполнение продолжается. |