如何指向类型绑定过程?假设我有一些外部子程序,它将一个指向一个只接受一个参数的函数的指针作为参数。
call integrator(f0)
如果在某处定义函数f0使其看起来像
,这将起作用function f0(x) result(val)
... do something...
end function
但是现在我有一个带有一些类型绑定过程的SomeClass类型。其中一个类型绑定程序是
function integrand(this,x) result(val)
class(SomeClass), intent(in) :: this
...do something...
end function
我有一个相同类型的另一个类型绑定过程想要调用上面的子例程将第一个类型绑定过程传递给它,但我不知道如何编写它!让我先尝试一下,有点天真,
function CalculateIntegral(this) result(val)
class(SomeClass), intent(in) :: this
call integrator(this%integrand)
end function
这给了我
call integrator(this%integrand)
1
Error: Expected argument list at (1)
我从this discussion学到的是因为这个%integrand没有返回指向函数的指针,而是绑定到函数。
所以,现在我来试试这个
function CalculateIntegral(this) result(val)
class(SomeClass), intent(in) :: this
call integrator(integrand)
end function
并且它编译但是给了我一个Memory Reference错误,因为它试图将值(x)传递给类(SomeClass)类的参数(即,这个)。
因此,如果这个%integrand只给我一个绑定而不是一个指向类型绑定成员过程的指针,那么如何在没有第一个" this&#的情况下将我的一个类型绑定成员过程传递给外部子例程34;争论阻碍了吗?
注意:我曾经在python中编码,其中self.integrand可以传递给外部函数,一切都会好的。
答案 0 :(得分:1)
按照@ Vladimir评论中的链接,传递内部程序似乎适用于最近的编译器(注意:我认为第一个例子是下面代码中最简单和最好的):
module mymod
implicit none
type mytype
real :: q
contains
procedure :: calc_integral
end type
contains
function calc_integral( this, a, b ) result( ans )
class(mytype) :: this
real :: a, b, ans
call integrator( myfunc, a, b, ans )
contains
function myfunc( x ) result( val )
real :: x, val
val = this% q * x
end function
endfunction
end module
!! Some external library.
subroutine integrator( func, a, b, ans )
external :: func
real :: a, b, ans, func
ans = func( a ) + func( b )
end
program main
use mymod
type(mytype) :: mt
mt% q = 100.0
print *, mt% calc_integral( 1.0, 2.0 ) !! gives 300.0
end
在上面的代码中,也可以将模块过程传递给integrator()
(而不是传递内部过程),但在这种情况下,this_
可能需要myfunc()
之类的内容。访问类型组件(参见下一个案例)。
下面是另一种以不同方式传递被积函数的尝试。
这里,指向模块过程myfunc()
的指针传递给integrator()
module mymod
implicit none
interface
function integrand_i( x ) result( val )
real :: x, val
endfunction
endinterface
type mytype
real :: q
procedure(integrand_i), nopass, pointer :: integrand
contains
procedure :: init
endtype
class(mytype), pointer :: this_
contains
subroutine init( this )
class(mytype), target :: this
this% integrand => myfunc
this_ => this
endsubroutine
function myfunc( x ) result( val )
real :: x, val
val = this_ % q * x
endfunction
end module
! subroutine integrator() here
program main
use mymod
type(mytype) :: mt
real :: ans
call mt% init
mt% q = 100.0
call integrator( mt% integrand, 1.0, 2.0, ans )
print *, ans
end
看起来有点类似于OP在问题中的原始方法(在我看来)。
另一种(不工作)方法是修改上面的init()
,以便获得指向内部过程的指针
subroutine init( this )
class(mytype) :: this
this% integrand => myfunc
contains
function myfunc( x ) result( val )
real :: x, val
val = this % q * x
endfunction
endsubroutine
但是这不起作用,因为退出init()时内部过程变得不确定。同样,以下似乎也不起作用(它甚至不用gfortran4.8.2编译)。
type mytype
...
contains
procedure :: integrand
endtype
...
function integrand( this ) result( ptr )
class(mytype) :: this
procedure(integrand_i), pointer :: ptr
ptr => myfunc
contains
function myfunc( x ) result( val )
real :: x, val
val = this % q * x
endfunction
endfunction
program main
...
call integrator( mt% integrand, 1.0, 2.0, ans )