Typgebundene Prozedur als Argumente
-
20-12-2019 - |
Frage
Ich möchte eine typgebundene Prozedur (als externe Funktion) wie folgt an eine andere Funktion übergeben:
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 erzeugt diesen Fehler :
write(*,*) s(t%f)
1
Error: Expected argument list at (1)
Aber was ich tun kann, ist:
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
Ich denke, das Problem hängt damit zusammen Typgebundene Prozeduren als Argumente übergeben, aber ich sehe im Moment nicht, wie mir die Antworten dort helfen können.
BEARBEITEN:
Ein besseres Beispiel, das (hoffentlich) die Schwierigkeit zeigt:
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
BEARBEITEN II:Ok, die Wrapper funktionieren immer noch in Kombination mit einem Zeiger:
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
Dies ist sicherlich keine schöne Lösung, aber zumindest funktioniert es.
Lösung
Sie können einen Wrapper schreiben.Dies ist die einfachste Version.Erfordert die Übergabe einer internen Funktion als Dummy-Argument (F2008), aber Sie könnten den Wrapper auch in einem Modul deklarieren, wenn die t
kann dort sein.
Hinweis: Ich habe die Deklaration des Prozedurarguments in geändert s
zu etwas Modernerem - dem Schnittstellenblock.
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
Der Grund für Ihren Fehler ist in den Antworten auf die verknüpfte Frage gut beschrieben. Sie können typgebundene Prozeduren nicht so übergeben, wie Sie es versucht haben.