Type Bound Procedura come argomenti
-
20-12-2019 - |
Domanda
Voglio passare una procedura legata al tipo (come funzione esterna) a un'altra funzione come segue:
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 Produce dà questo errore:
write(*,*) s(t%f)
1
Error: Expected argument list at (1)
.
Ma quello che posso fare è:
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
.
Penso che il problema sia correlato a Passare le procedure legate al tipoCome argomenti , ma non vedo nel momento in cui le risposte possono aiutarmi.
Modifica:
Un esempio migliore che (si spera) mostra la difficoltà:
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
.
Modifica II: Ok, i wrapper funzionano ancora in combinazione con un puntatore:
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
.
Questo non è certamente una soluzione bellissima ma almeno funziona.
Soluzione
Puoi scrivere un wrapper.Questa è la versione più semplice.Richiede il passaggio della funzione interna come argomento fittizio (F2008), ma è possibile dichiarare anche il wrapper in un modulo, se il t
può apillare lì.
Nota Ho modificato la dichiarazione dell'argomento della procedura in s
a qualcosa di più moderno - il blocco di interfaccia.
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
.
Il motivo del tuo errore è ben descritto nelle risposte alla domanda collegata, non è possibile passare le procedure legate al tipo il modo in cui hai provato.