Fortran:指向方法的过程指针

Fortran: procedure pointer to method

我处于以下情况:我有一个对象必须用一些输入参数 x 初始化(不着急)。然后它有一个方法 do_work 必须 运行 (快速)。现在,根据 xdo_work 可以是函数 f1f2。当然我可以在调用 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 时,您将(除非以某种方式优化)有一个指针查找的开销。这可能会也可能不会干扰某些可能的编译器优化。真的很难说这是否会真正有意义地减慢任何东西而不仅仅是尝试查看,并且 运行 一个代码分析器来找出答案。