Таким образом, поскольку в функции copy__i f () вызов функции-предиката имеет вид вызова обычной функции, передавать методы в качестве аргумента нельзя. Ограничение достаточно существенное, поэтому хотелось бы от него избавиться.
Первое решение, которое приходит в голову, состоит в том, чтобы передавать в функцию-фильтр copy_if () не указатель на функцию, а объект, в котором реализована соответствующая функция в виде метода. Изменений в шаблоне функции-фильтра это потребует минимальных — достаточно задать вызов предиката как вызов метода (листинг 12.8).
Листинг 12.8с Предикат как объект
class D // класс-оболочка функции {public: bool function(const int &a) const {return a%2; } };
template <class Inputlterator, class Outputlterator, class Predicate > void copy_if( Inputlterator first, Inputlterator last, Outputlterator result, const Predicate &0bj
) {for ( ; first != last; ++first) if (Obj.function(*first)) // вызов метода { *result = *first; ++result; }return; }
Это решение нас устроить не может, так как практически не отличается от предыдущего — мы только сменили один вид параметра на другой. Теперь в предикат невозможно передать указатель на функцию. Кроме того, нельзя забывать, что метод в классе должен называться всегда одинаково — тем именем, которое указано в вызове. И еще одно замечание: мы объявили метод functionQ константным, так как параметр передается по константной ссылке. Если нас это не устраивает, то нужно передавать параметр по значению, как в предыдущем варианте функции copy_i f ().
Необходимо такое решение, которое действительно было бы универсальным и обеспечивало работу и с функциями, и с методами. Для этого нам нужно сначала разобраться с перегрузкой операции operator(), реализующей вызов функции в классе.
Мы уже перегружали эту операцию для индексирования динамических массивов (см. главу 5). Однако в данном случае мы перегрузим ее для использования «по прямому назначению» — как операцию вызова функции.
Традиционно класс, в котором перегружена операция operator (), называют функциональным классом, или классом-функтором. Объект такого класса называют объектом-функцией, функциональным объектом (см. п. 20.3 в [1]), или просто функтором. Функтор представляет собой объект, который ведет себя, как функция.
ПРИМЕЧАНИЕ
Как справедливо отмечено в [28], таковыми являются не только функциональные объекты, но и указатели на функции и методы. Однако мы будем придерживаться традиционного взгляда, считая функторами только объекты-функции.
Опубликовал Kest
January 13 2014 10:53:49 ·
1 Комментариев ·
2895 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Alex January 14 2014 18:46:18
Интересные штуки эти функтору, сам недавно о них узнал. Немного добавлю ко всему сказанному в статье. Если популярно объяснить, то функторы нужны затем, чтобы заменить указатели на функции при обработке сложных структур данных. При этом функтор является объектом, который можно передавать и по значению. Использование функторов повышает инкапсуляцию и надежность программ.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.