我有一个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'中的那些全局变量。但是,我找不到一种方法来将'f'变为全局,或将其分配给全局函数。
有人有任何想法如何做到这一点?解决方案可以像你想要的一样hacky。
答案 0 :(得分:5)
这并不容易。在某些语言中,您可以将指针传递给所谓的closure
中的嵌套函数。这在Fortran(或C和类似语言)中是不可能的,因为数据会被更高功能的堆栈破坏。我建议你尝试使用函数对象,即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
答案 1 :(得分:2)
您可以使用过程指针做很多事情,构建一个其他函数组合的函数。有关代码示例,请参阅Function pointer arrays in Fortran。