简体   繁体   English

Fortran:指向方法的过程指针

[英]Fortran: procedure pointer to method

I'm in the following situation: I have an object that must be initialized (without hurry) with some input parameter x .我处于以下情况:我有一个 object 必须用一些输入参数x初始化(不着急)。 Then it has a method do_work that has to run (fast).然后它有一个必须运行(快速)的方法do_work Now, depending on x the do_work can be either function f1 or f2 .现在,根据xdo_work可以是 function f1f2 Of course I can choose among them when do_work is called, but, since I know the choice in advance, I was thinking to use a procedure pointer.当然,当do_work时,我可以在其中进行选择,但是,由于我事先知道选择,我正在考虑使用过程指针。

I produced the following MWE我制作了以下 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

It seems to work, but I'm rather new to (modern) Fortran and I would like to know whether I did something wrong/dangerous since I'm working with pointers.它似乎有效,但我对(现代)Fortran 相当陌生,我想知道我是否做错/危险,因为我正在使用指针。 I'm also curios if that abstract interface introduces some virtual function table lookup (I do not see why it should, but I'm a newbie, as I said)如果该abstract interface引入了一些虚拟 function 表查找,我也很好奇(我不明白为什么应该这样做,但正如我所说,我是新手)

To answer your questions in order:按顺序回答您的问题:

  • It doesn't look like you've done anything dangerous or wrong.看起来你没有做任何危险或错误的事情。 This looks to me like a good use case for procedure pointers, and your implementation looks good.这在我看来像是过程指针的一个很好的用例,而且你的实现看起来不错。
  • The abstract interface is basically just defining the "type signature" of the procedure pointer. abstract interface基本上只是定义过程指针的“类型签名”。 It doesn't add any overhead.它不会增加任何开销。
  • You will (unless it's somehow optimised out) have the overhead of a single pointer lookup every time you call fptr .每次调用fptr时,您都会(除非它以某种方式优化)有单指针查找的开销。 This might or might not interfere with some possible compiler optimisations.这可能会或可能不会干扰一些可能的编译器优化。 It's really hard to say whether this will actually meaningfully slow anything down without just trying it to see, and running a code profiler to find out.真的很难说这是否真的会有意义地减慢任何东西,而不仅仅是尝试查看并运行代码分析器来找出答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM