Итак, мы хотим передавать предикат алгоритму find_if() и чтобы этот предикат сравнивал элементы со значением, которое мы зададим как его аргумент. В частности, мы хотим написать примерно такой код:
void f(list& v, int x)
{
list::iterator p = find_if(v.begin(), v.end(),
Larger_than(31)); if (p!=v.end()) { /* мы нашли число, превышающее 31 */ }
list::iterator q = find_if(v.begin(), v.end(),
Larger_than(x));
if (q!=v.end()) { /* мы нашли число, превышающее x */ }
// . . .
}
Очевидно, что функция Larger_than должна удовлетворять двум условиям.
• Ее можно вызывать как предикат, например pred(*first).
• Она может хранить значение, например 31 или x, передаваемое при вызове.
Для того чтобы выполнить эти условия, нам нужен объект-функция, т. е. объект, ~* который ведет себя как функция. Нам нужен объект, поскольку именно объекты могут хранить данные, например значение для сравнения. Рассмотрим пример.
class Larger_than { int v; public:
Larger_than(int vv) : v(vv) { } // хранит аргумент
bool operator()(int x) const { return x>v; } // сравнение
};
Следует отметить, что это определение представляет собой именно то, что мы требовали от предиката. Теперь осталось понять, как это работает. Написав выражение Larger_than(31), мы (очевидно) создаем объект класса Larger_than, хранящий число 31 в члене v. Рассмотрим пример.
find_if(v.begin(),v.end(),Larger_than(31))
Здесь мы передаем объект Larger_than(31) алгоритму find_if() как параметр с именем pred. Для каждого элемента v алгоритм find_if() осуществляет вызов
pred(*first)
Это активизирует оператор вызова функции, т.е. функцию-член operator(), для объекта-функции с аргументом *first. В результате происходит сравнение значения элемента, т.е. *first, с числом 31.
Мы видим, что вызов функции можно рассматривать как результат работы оператора ( ), аналогично любому другому оператору. Оператор ( ) называют также
оператором вызова функции (function call operator) или прикладным оператором (application operator). Итак, оператор ( ) в выражении pred(*first) эквивалентен оператору Larger_than::operator(), точно так же, как оператор [] в выражении v[i] эквивалентен оператору vector::operator[ ].
|