Tipo de enlazado procedimiento como argumentos
-
20-12-2019 - |
Pregunta
Quiero pasar a un tipo atado procedimientos (como una función externa) a otra función como la siguiente:
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 da este error :
write(*,*) s(t%f)
1
Error: Expected argument list at (1)
Pero lo que puedo hacer es:
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
Creo que el problema está relacionado con Pasando de tipo obligado procedimientos como argumentos, pero no veo en el momento en que las respuestas no me puede ayudar.
EDITAR:
Un mejor ejemplo de lo que (esperemos) muestra la dificultad:
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:Ok, los contenedores siguen trabajando en combinación con un puntero:
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
Ciertamente, esta no es una buena solución, pero al menos funciona.
Solución
Usted puede escribir un contenedor.Este es el más sencillo de la versión.Requiere pasar a la función interna como un maniquí argumento (F2008), pero puede declarar el contenedor en un módulo demasiado, si el t
puede bee allí.
Nota: he cambiado la declaración de los argumentos de los procedimientos en s
a algo más moderno - el bloque de interfaz.
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
La razón de su error está bien descrito en las respuestas a la pregunta vinculada, no puede pasar de tipo obligado procedimientos de la forma en que se trató de.