Стандартные алгоритмы также используют функциональные объекты, или operator()
так, что его можно вызвать как функцию. Функтор, который возвращает bool
(и не поддерживает состояния, и, следовательно, называется
Имя типа | Описание |
---|---|
UnPred | Унарный предикат. Принимает один аргумент и возвращает bool |
BinPred | Бинарный предикат. Принимает два аргумента и возвращает bool |
UnFunc | Унарная функция. Принимает один аргумент и возвращает некое значение |
BinFunc | Бинарная функция. Принимает два аргумента и возвращает некое значение |
В большинстве случаев там, где требуется аргумент в виде функтора, может использоваться указатель на функцию. При использовании термина «функтор» я также подразумеваю указатель на функцию, если не указано иного.
7.1. Перебор элементов контейнера
Имеется диапазон итераторов — скорее всего, из стандартного контейнера — и стандартные алгоритмы не удовлетворяют вашим требованиям, так что вам требуется выполнить итерации самостоятельно.
Для доступа к элементам контейнера и перехода от одного элемента к другому используйте iterator
или const_iterator
. В стандартной библиотеке алгоритмы и контейнеры взаимодействуют с помощью итераторов, и одной из базовых идей стандартных алгоритмов является то, что они избавляют вас от необходимости непосредственного использования итераторов, за исключением тех случаев, когда вы пишете собственный алгоритм. И даже в этом случае вы должны понимать различные типы итераторов с тем, чтобы эффективно использовать стандартные алгоритмы и контейнеры. Пример 7.1 представляет некоторые простые способы использования итераторов.
#include <iostream>
#include <list>
#include <algorithm>
#include <string>
using namespace std;
static const int ARRAY_SIZE = 5;
template<typename T, typename FwdIter>
FwdIter fixOutliersUBound(FwdIter p1,
FwdIter p2, const T& oldVal, const T& newVal) {
for ( ; p1 != p2; ++p1) {
if (greater<T>(*p1, oldVal)) {
*p1 = newVal;
}
}
}
int main() {
list<string> lstStr;
lstStr.push_back('Please');
lstStr.push_back('leave');
lstStr.push_back('a');
lstStr.push_back('message');
// Создать итератор для последовательного перебора элементов списка
for (list<string>::iterator p = lstStr.begin();
p != lstStr.end(); ++p) {
cout << *p << endl;
}
// Или можно использовать reverse_iterator для перебора от конца
// к началу, rbegin возвращает reverse_iterator, указывающий
// на последний элемент, a rend возвращает reverse_iterator, указывающий
// на один-перед-первым.
for (list<string>::reverse_iterator p = lstStr.rbegin();
p != lstStr.rend(); ++p) {
cout << *p << endl;
}
// Перебор диапазона элементов
string arrStr[ARRAY_SIZE] = {'My', 'cup', 'cup', 'runneth', 'over'};
for (string* p = &arrStr[0];
p != &arrStr[ARRAY_SIZE]; ++p) {
cout << *p << endl;