Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Функтор |
Автор: knut 14.12.2006, 16:12 |
Добрый день.Меня мучает вопрос касающий функторов. 1.Вот если главная задаяча функтора это соxраниние даныx между вызовами функции то не получиться это все зделать с помощью статическиx переменныx?(Можно реальный пример с использ.функторов или сылку где можно прочитать)В чем фишка функтора? 2.Аналог делегата в с++.Есть вообще связь между делегатом и функтором? Вообще скинте сылки где прочитать буду признателен ![]() |
Автор: JackYF 14.12.2006, 16:53 |
Аналог делегата - указатель на функцию. Подробнее - гугл в помощь. Одна из главных задач функтора - возможность передачи функции как параметра шаблона. Для этого в классе перегружается operator() и выходит функтор. А сохранение переменных между вызовами - делай как хочешь. Но лучше нестатически, потому что у тебя могут сосуществовать несколько разных экземпляров функтора одновременно. |
Автор: knut 14.12.2006, 17:18 | ||||
т.е экземпляр класса ведет себя как функция я правельно понял?если да то что это нам дает?() можем писать так
|
Автор: zabivator 14.12.2006, 17:33 |
knut, да, именно так. Вообще говоря, тема функторов очень обширна... Я прочитал когда твой пост думал отвечать-не отвечать, в итоге забил =) Читай, например, Александреску, или новые сложные от Саттера - там эта тема исчерпывающим образом раскрыта. |
Автор: JackYF 14.12.2006, 18:02 |
Передавать как параметр шаблона, например, в стандартные контейнеры STL(допустим, функцию сравнения двух элементов). |
Автор: Любитель 14.12.2006, 18:08 |
Не совсем. Не помню, как в С# 1.0, но уже во второй версии, можно делать делегаты прямо в коде - по сути лямбда-функции. В плюсах для этого нет языковой поддержки (я надеюсь - и не будет, это не в стиле плюсов), но есть ФП в стиле STL, и (как его развитие) - в стиле буста (да, да и ещё раз да). std::bind1st, std::bind2nd, boost::bind, boost::lambda, boost::signals, boost::function - это приплющенное функциональное программирование. Собственно функторы - это основа ФП в плюсах. Биндить обычные функции (во что?), генерить лямбды (что мы получим?) и прочее - как сие представить без функторов. В этом мне сильно не нравится кутешные сигнал/слоты, которые реализуется как таблицы строка => казатель на функцию. Очень часто мне бы хотелось рантайм генерацию слотов (как объектов). boost::signals явно рулит, но не доделан: 1. непотокобезопасный 2. нет возможности разделения на коннект слотов, и инициация сигнала (часто коннектить может кто угодно, а инициация - прайват или протектед). |
Автор: zabivator 14.12.2006, 18:12 |
Любитель, а в чем именно проявляется его непотокобезопасность? Я это читал в документации, но не догнал. |
Автор: JackYF 14.12.2006, 18:17 |
Я же сказал - "аналог", а не то же самое ![]() |
Автор: knut 14.12.2006, 18:28 | ||
JackYF,
а что это без функтора нельзя зделать? |
Автор: Daevaorn 14.12.2006, 18:33 |
Ты сам уже написал вначале, что функтор позволяет сохранять состояния между вызывами. Обчыная функция такой гибкостью не обладает(почти). |
Автор: JackYF 14.12.2006, 18:33 | ||
В большинстве ситуаций с STL - контейнерами - да.
Здесь Compare - обязательно класс. Функция - это не класс, поэтому ты можешь передать в шаблон только функтор. |
Автор: JackYF 14.12.2006, 19:11 | ||
Все иронизируешь... ![]() А ты? Сие не только не будет работать, оно даже не откомпилируется. (Вообще, я там раньше имел, конечно же, ввиду set, но это не суть важно). GCC: error: invalid cast to function type `bool ()()' Так-то. Добавлено @ 19:16 Я против boost::function ничего не имею... Но мне пока она не была нужна. |
Автор: Любитель 15.12.2006, 11:04 | ||||||
JackYF, не внимательно читаем. Начинаю цитировать самого себя: сновываясь == основываясь То есть всё что мы знали о map - твоё обявление. Я не думал (или не хотел думать) о std::map. Хотя соглашусь, для совместимости с функторами надо было написать так (использовать тип указателя на функцию, а не функции - как я написал):
А то, что я сказал работает. При соответствующем объявлении класса map (усекаем до минимума):
Любой нормальный компилер проглотит. Здесь есть правда ошибка - ... логическая. Compare по идее должна что-то сравнивать, а уна сие не так. ![]() И всё же можно добавить функцию для установки компаратора. Если мы пишем, как я написал ранее, то придётся добавить пару звёздочек (после Compare - в функции и в обяъвлении поля). Особо старательные могут написать обобщённый код (с boost::enable_if), чтобы воспринимались как функции, так и указатели на них (и совместимые по семантике вызова с последними функторы). Для простоты считаем, что мы всё же пишем test<bool (*)()> (подчёркиваю - сие явно не функтор). Можно написать сию (абсолютно бесполезную) вещь:
Замечу, что Compare не обязан возвращать bool, он должен к нему приводится. Прикол в том, что f одновременно и указатель на функцию и сама функция. Интересен тот факт, что для функций-членов (по стандарту) однако наджо использовать амперсанд. ТАк уж есть. По сабжу - повторюсь функтор нужен для ФП (функционального программирования). Если нитересно - могу напридумывать тривиальных примеров (не хочется зря писать - если не интересно). Я сипипишное ФП очень люблю, потому меня сия тема интересует. В какой-то мере... Просто, когда я ещё в школе учился, жил в небольшом таком городке и сидел дома на диалапе ![]() ![]() Добавлено @ 11:18 ЗЫ коммент в f я зря поставил ![]() |
Автор: knut 15.12.2006, 12:24 | ||
ну давай ![]() ![]() |