Fortran:指向方法的过程指针
Fortran: procedure pointer to method
我处于以下情况:我有一个对象必须用一些输入参数 x
初始化(不着急)。然后它有一个方法 do_work
必须 运行 (快速)。现在,根据 x
,do_work
可以是函数 f1
或 f2
。当然我可以在调用 do_work
时从中选择,但是,因为我事先知道选择,所以我想使用过程指针。
我制作了以下MWE
module delegate_m
implicit none
private
type delegate
private
integer :: x
procedure(delegate_function), private, pointer :: fptr
contains
private
procedure:: f2
procedure :: f1
procedure, public :: do_work
end type delegate
interface delegate
module procedure :: init_delegate
end interface delegate
abstract interface
integer function delegate_function(self,y)
import :: delegate
class(delegate) :: self
integer :: y
end function delegate_function
end interface
public :: delegate
contains
type(delegate) function init_delegate(x)
implicit none
integer, intent(in) :: x
init_delegate%x = x
if (modulo(x, 2) == 0) then
init_delegate%fptr => f1
else
init_delegate%fptr => f2
end if
end function init_delegate
integer function f1(self,y)
implicit none
class(delegate) :: self
integer :: y
f1 = y * self%x
end function f1
integer function f2(self,y)
implicit none
class(delegate) :: self
integer :: y
f2 = (y ** 2) * self%x
end function f2
integer function do_work(self, x, y)
implicit none
class(delegate) :: self
integer:: x, y
do_work = self%fptr(x) - y
end function do_work
end module delegate_m
program test
use delegate_m
implicit none
type(delegate) :: d1, d2
d1 = delegate(45)
d2 = delegate(44)
write (*,*) d1%do_work(2, 3)
write (*,*) d2%do_work(2, 3)
end program test
它似乎有效,但我对(现代)Fortran 比较陌生,我想知道我是否做了一些事情 wrong/dangerous 因为我正在使用指针。我也很好奇 abstract interface
是否引入了一些虚函数 table 查找(我不明白为什么要这样做,但正如我所说,我是新手)
按顺序回答您的问题:
- 看起来你没有做过任何危险或错误的事情。在我看来,这像是一个很好的过程指针用例,而且您的实现看起来不错。
-
abstract interface
基本上只是定义过程指针的“类型签名”。它不会增加任何开销。
- 每次调用
fptr
时,您将(除非以某种方式优化)有一个指针查找的开销。这可能会也可能不会干扰某些可能的编译器优化。真的很难说这是否会真正有意义地减慢任何东西而不仅仅是尝试查看,并且 运行 一个代码分析器来找出答案。
我处于以下情况:我有一个对象必须用一些输入参数 x
初始化(不着急)。然后它有一个方法 do_work
必须 运行 (快速)。现在,根据 x
,do_work
可以是函数 f1
或 f2
。当然我可以在调用 do_work
时从中选择,但是,因为我事先知道选择,所以我想使用过程指针。
我制作了以下MWE
module delegate_m
implicit none
private
type delegate
private
integer :: x
procedure(delegate_function), private, pointer :: fptr
contains
private
procedure:: f2
procedure :: f1
procedure, public :: do_work
end type delegate
interface delegate
module procedure :: init_delegate
end interface delegate
abstract interface
integer function delegate_function(self,y)
import :: delegate
class(delegate) :: self
integer :: y
end function delegate_function
end interface
public :: delegate
contains
type(delegate) function init_delegate(x)
implicit none
integer, intent(in) :: x
init_delegate%x = x
if (modulo(x, 2) == 0) then
init_delegate%fptr => f1
else
init_delegate%fptr => f2
end if
end function init_delegate
integer function f1(self,y)
implicit none
class(delegate) :: self
integer :: y
f1 = y * self%x
end function f1
integer function f2(self,y)
implicit none
class(delegate) :: self
integer :: y
f2 = (y ** 2) * self%x
end function f2
integer function do_work(self, x, y)
implicit none
class(delegate) :: self
integer:: x, y
do_work = self%fptr(x) - y
end function do_work
end module delegate_m
program test
use delegate_m
implicit none
type(delegate) :: d1, d2
d1 = delegate(45)
d2 = delegate(44)
write (*,*) d1%do_work(2, 3)
write (*,*) d2%do_work(2, 3)
end program test
它似乎有效,但我对(现代)Fortran 比较陌生,我想知道我是否做了一些事情 wrong/dangerous 因为我正在使用指针。我也很好奇 abstract interface
是否引入了一些虚函数 table 查找(我不明白为什么要这样做,但正如我所说,我是新手)
按顺序回答您的问题:
- 看起来你没有做过任何危险或错误的事情。在我看来,这像是一个很好的过程指针用例,而且您的实现看起来不错。
-
abstract interface
基本上只是定义过程指针的“类型签名”。它不会增加任何开销。 - 每次调用
fptr
时,您将(除非以某种方式优化)有一个指针查找的开销。这可能会也可能不会干扰某些可能的编译器优化。真的很难说这是否会真正有意义地减慢任何东西而不仅仅是尝试查看,并且 运行 一个代码分析器来找出答案。