Passing a generic procedure to a function as actual argument

后端 未结 2 395
死守一世寂寞
死守一世寂寞 2021-01-12 07:25

I am attempting to pass a generic procedure as an actual argument to a function:

module mymod
implicit none

interface func
  module procedure :: func1
  mod         


        
相关标签:
2条回答
  • 2021-01-12 07:35

    No, this is not allowed. Actually, you cannot even pass generic INTRINSIC functions as dummy arguments.

    A standard compliant way is to use the right specific functions directly. With INTRINSIC functions you sometimes must write a wrapper for the right kind, when the specific doesn't have a standard name.

    For example:

      call integrate(derf,0.,1.)
    
      contains
        function derf(x)
          real(dbl) :: derf
          real(dbl), intent(in) :: x
          derf = erf(x)
        end function
      end
    

    is necessary if you want to pass the double precision real (or any other) version of erf() because there is no specific function available.

    0 讨论(0)
  • 2021-01-12 07:45

    The Fortran standard doesn't allow one to pass generic procedures as arguments. In order to pass intrinsic functions/subroutines one must resort to user-defined wrapper procedures.

    module mymod
    
        ! Explicit typing only
        implicit none
    
        ! Declare procedure interface
        interface
           function my_func(x, y) result (return_value)
             real, intent(in) :: x, y
             real             :: return_value
           end function my_func
        end interface
    
    contains
    
        function func1(x) result (return_value)
           real,intent(in) :: x
           real            :: return_value
    
           return_value = 2*x
    
        end function func1
    
        function func2(x, y) result (return_value)
           real, intent(in) :: x, y
           real             :: return_value
    
           return_value = 2*x + 3*y
    
        end function func2
    
        function func3(user_defined_func, x, y) result (return_value)
           procedure(my_func)  :: user_defined_func
           real, intent(in)    :: x, y
           real                :: return_value
    
           return_value = user_defined_func(x,y)
    
        end function func3
    
    end module mymod
    
    program main
    
        use ISO_Fortran_env, only: &
           stdout => OUTPUT_UNIT, &
           compiler_version, &
           compiler_options
    
        use mymod
    
        ! Explicit typing only
        implicit none
    
        write (stdout, *) func3(func2, 2.0, 3.0)
        write (stdout, *) func3(foo, 2.0, 3.0)
        write (stdout, *) func3(my_atan2, 2.0, 3.0)
    
        print '(/4a/)', &
        ' This file was compiled using ', compiler_version(), &
        ' using the options ', compiler_options()
    
    contains
    
        ! A user defined function
        function foo(x, y) result (return_value)
           real, intent(in) :: x, y
           real             :: return_value
    
           return_value = 42
    
        end function foo
    
        ! A wrapper function to invoke the intrinsic atan2
        function my_atan2(x, y) result (return_value)
           real, intent(in) :: x, y
           real             :: return_value
    
           return_value = atan2(x,y)
    
        end function my_atan2
    
    end program main
    

    yields

    gfortran -std=f2008ts -o main.exe  mymod.f90 main.f90
    ./main.exe
       13.0000000    
       42.0000000    
      0.588002622    
    
     This file was compiled using GCC version 6.1.1 20160802 using the options -mtune=generic -march=x86-64 -std=f2008ts
    
    0 讨论(0)
提交回复
热议问题