Игаль *    (yigal_s) wrote,
Игаль *   
yigal_s

В С++ есть две "культуры" конструирования функций как объектов.

С одной стороны - функторы, тип которых отражает практически полностью их начинку. Т.е. если внутри этой функции будет сложение, то в навороченном объекте, функцию эту имплементирующем, а так же в его типе, будет какой-то подобъект "add", реализующий сложение, собственно сам объект представляет собой дерево более элементарных объектов, исполняющих математические действия, bind-ящих константы вместо каких-то отдельных аргументов итд., а его темплейтный тип имеет в качестве аргументов другие темплейтные типы итд. опять же деревом, и среди этих типов будет и add, и bind, и всё остальное прочее что мы по дороге в наш функтор запихали. И, что важно, функция вызова подобного функционального объекта не виртуальна. Подобные функции стали делать в STL, продолжили делать в boost и даже лямбда-функция в С++ в какой-то отдаленной мере отражает этот же подход, поскольку её тип уникален.

С другой стороны, построив с грехом пополам в С++ функтор как композицию объектов, или же создав лямбду, его или её можно присвоить инстансу класса std::function, который в своих темплейтных параметрах несет только сигнатуру необходимого функционального вызова, в отношении всей же остальной начинки выполняет типичный type erasure. И далее работать уже с std::function. Или же можно работать с функциональными объектами, которые имеют виртуальную функцию вызова (не как в STL или boost), тем самым осуществляя type erasure посредством обращения с классом функции через её базовый интерфейс.

Первый подход, очевидно, вызывает в С++ генерацию нового кода для каждой функции ИСПОЛЬЗУЮЩЕЙ наш функциональный объект, использование же класса "function" позволяет это избежать.

Мне интересно - какие есть принципиальные случаи, когда первый подход в принципе не работает? Один случай я уже знаю - это когда мы динамически генерим функтор по каким-то входным данным, скажем, пользователь может написать выражение y=sin(2*x), мы это выражение распарсиваем и строим функциональный объект, вычисляющий данное выражение. А вот если нет у нас юзеровского ввода, могут ли тем не менее быть ситуации, когда вариант с полной статической типизацией функтора в С++ не срабатывает? Ну, наверное, еще какая-нибудь задача, где нам надо сгенерить и перебрать какой-нибудь класс арифметических выражений.

Что-нибудь ещё менее вычурное из задач, где статическая типизация не подходит, имеется ли?
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 5 comments