Type Binding Procedure as Arguments

I want to pass type binding procedures (as an external function) to another function as follows:

module mod1 implicit none type type1 real :: a contains procedure,pass :: f end type contains real function f(y,e) class(type1), intent(in) :: y real,intent(in) :: e f=y%a+e end function end module program test use mod1 type(type1) :: t t%a=3e0 write(*,*) s(t%f) contains real function s(g) real,external :: g s=g(5e0)+2e0 end function end program 

gfortran produces this error:

  write(*,*) s(t%f) 1 Error: Expected argument list at (1) 

But I can do this:

 program test t%a=3e0 write(*,*) s(k) contains real function s(g) real,external :: g s=g(5e0)+2e0 end function real function k(e) real,intent(in) :: e k=3e0+e end function end program 

I think the problem is with the procedures for passing the type of the type as arguments , but at the moment I do not see how the answers to them can help me.

EDIT:

The best example that (hopefully) shows the difficulty:

 module mod2 implicit none contains real function s(g) interface real function g(x) real, intent(in) :: x end function end interface s=g(5e0)+2e0 end function end module module mod1 use mod2 type type1 real :: a contains procedure,pass :: f procedure,pass :: h end type contains real function f(y,e) class(type1), intent(in) :: y real,intent(in) :: e f=y%a+e end function real function h(y) class(type1), intent(inout) :: y h=s(y%f) end function end module program test use mod1 type(type1) :: t t%a=3e0 write(*,*) t%h end program 

EDIT II: Well, wrappers still work in combination with a pointer:

 module mod2 implicit none contains real function s(g) interface real function g(x) real, intent(in) :: x end function end interface s=g(5e0)+2e0 end function end module module mod1 use mod2 type type1 real :: a contains procedure,pass :: f procedure,pass :: h end type class(type1),pointer :: help_w contains real function f(y,e) class(type1), intent(in) :: y real,intent(in) :: e f=y%a+e end function real function h(y) class(type1), intent(inout),target :: y help_w => y h=s(wrap) end function function wrap(x) real,intent(in) :: x wrap=help_w%f(x) end function end module program test use mod1 type(type1) :: t t%a=3e0 write(*,*) t%h() end program 

This, of course, is not a beautiful solution, but at least it works.

+1
source share
1 answer

You can write a wrapper. This is the simplest version. It is required to pass an internal function as a dummy argument (F2008), but you can also declare a wrapper in a module if t can be there.

Note. I changed the declaration of the procedure argument in s to something more modern - the interface block.

 program test use mod1 type(type1) :: t t%a=3e0 write(*,*) s(wrap) contains real function s(g) interface real function g(x) real, intent(in) :: x end function end interface s=g(5e0)+2e0 end function function wrap(x) real, intent(in) :: x wrap = t%f(x) end function end program 

The reason for your error is well described in the answers to a related question, you cannot pass type binding procedures like you tried.

+1
source

Source: https://habr.com/ru/post/1246992/


All Articles