Динамическое создание функции из другой функции
У меня есть подпрограмма Fortran 90, которая принимает функцию в качестве аргумента, и я хотел бы передать измененную версию этой функции в другую подпрограмму. Я хочу, чтобы программа выглядела примерно так:
subroutine foo(f, ...)
real :: pt(2), dir(2)
interface
function f(x) result(y)
real, intent(in) :: x(2)
real :: y
end function f
end interface
pt = ...
dir = ...
!! Somehow create g(x) = f(pt + x*dir)
call bar(g)
end subroutine foo
subroutine bar(g)
interface
function g(x) result(y)
real, intent(in) :: x
real :: y
end function g
end interface
!! Do stuff with g
end subroutine bar
Мне удалось сделать нечто подобное, когда "g" нужно использовать только обычные переменные, а не функцию. В этом случае я сделал ее глобальной функцией, используя глобальные переменные, и назначил этим глобальным переменным в 'foo'. Однако я не могу
2 ответа
Это не так просто. В некоторых языках вы можете передавать указатели на вложенные функции в так называемом closure
, Это невозможно в Фортране (или Си и подобных языках), потому что данные уничтожаются с помощью стека высшей функции. Я хотел бы предложить вам попробовать функциональные объекты, т.е. class
с function pointer
(или более) и данные, необходимые для функции. Таким образом, вы можете даже создавать функциональные композиции и подобные функциональные вещи.
Подробнее о концепции http://en.wikipedia.org/wiki/Function_object
Ниже приведен пример для объекта функции для композиции двух функций с одним аргументом:
module ComposeObj
use Parameters
use AritmFunctions
implicit none
private
public Compose
type Compose
private
procedure(fce),pointer,nopass :: f1 => null(),f2=>null()
contains
procedure,public :: call => helper
endtype Compose
interface Compose
procedure NewCompose
end interface
contains
function NewCompose(f,g)
procedure(fce) :: f,g
type(Compose) :: NewCompose
NewCompose%f1 => f
NewCompose%f2 => g
end function NewCompose
pure real(KND) function helper(this,x)
class(Compose),intent(in) :: this
real(KND),intent(in) :: x
helper = this%f1(this%f2(x))
end function helper
end module ComposeObj
Вы можете многое сделать с помощью указателей процедур, создавая функцию, которая является комбинацией других функций. Посмотрите массивы указателей на функции в Фортране для примера кода.