Pointer to a function inside a derived type on a module in fortran
I guess I could easily use some help here, since I'm messing around with some fortran 2003 but can't seem to understand how to do things really. The fact is that I need to write a fortran code that declares, inside a module, a new data type that has as one of its members a pointer to a real function. Something like
module new_mod type my_type real*8 :: a, b (here something that declares a real*8 function), pointer :: ptr end type my_type end module_new module funcs real*8 function function1(x) real*8 :: x function1 = x*x end function function1 real*8 function function2(x) real*8 :: x function2 = x*x end function function2 end module funcs
then in the main program I would like to have something like
program my_prog use module_new use module_funcs implicit none real*8 :: y, z type(my_type) :: atom ... atom%ptr => function1 y = atom%ptr(x) ... atom%ptr => function2 z = atom%ptr(x) end program my_prog
so the main idea is that module_new contains a type that has a pointer to a real function. This pointer in th eobjects of the new type I must be able to point to different functions in the main program. I have seen one can do similar things with abstract interfaces and such, but honestly, I'm in a mess here. If someone could help, I'll appreciate that. Cheers...
Well, that is not really the type of question you would send to stackoverflow, but actually your code needs only a "slight improvement" (by appropriate definition of slight) to work:
module accuracy implicit none integer, parameter :: dp = kind(1.0d0) end module accuracy module typedef use accuracy implicit none type :: mytype real(dp) :: aa, bb procedure(myinterface), pointer, nopass :: myfunc end type mytype abstract interface function myinterface(xx) import :: dp real(dp), intent(in) :: xx real(dp) :: myinterface end function myinterface end interface end module typedef module funcs use accuracy implicit none contains function func1(xx) real(dp), intent(in) :: xx real(dp) :: func1 func1 = xx end function func1 function func2(xx) real(dp), intent(in) :: xx real(dp) :: func2 func2 = 2.0_dp * xx end function func2 end module funcs program test use accuracy use typedef use funcs implicit none real(dp) :: xx type(mytype) :: atom xx = 12.0_dp atom%myfunc => func1 print *, atom%myfunc(xx) atom%myfunc => func2 print *, atom%myfunc(xx) end program test
There are several things to be worth to mentioned:
You should use one global parameter for your accuracy (see module accuracy) and forget about real*8.
Your procedure pointer in your derived type needs an interface, which is provided within the following abstract interface block (see 'abstract interfaces' in a good F2003 book).
You need the nopass option for the procedure pointer in the derived type as otherwise Fortran will assume that the first parameter passed to the function/subroutine is the derived type itself (see 'type bound procedures' in a good F2003 book).
Finally, although rather obvious: You should definitely read a book about the Fortran 2003 features if you are serious about using them in a production code.