with transact terminar stored salir from como stored-procedures module fortran procedure derived-types

stored-procedures - transact - stored procedure with return value sql



Fortran guardar procedimiento como propiedad en tipo derivado (1)

¿Es posible almacenar un procedimiento como una propiedad de un tipo derivado? Estaba pensando en algo como:

module funcs_mod public :: add contains function add(y,z) result (x) integer,intent(in) :: y,z integer :: x x = y + z end function end module module type_A_mod use funcs_mod public :: type_A,set_operator type type_A procedure(),pointer,nopass :: operator end type contains subroutine set_operator(A,operator) external :: operator type(type_A),intent(inout) :: A A%operator => operator end subroutine function operate(A,y,z) result(x) type(type_A),intent(in) :: A integer,intent(in) :: y,z integer :: x x = A%operator(y,z) end function end module program test use type_A_mod use funcs_mod type(type_A) :: A call set_operator(A,add) write(*,*) operate(A,1,2) end program

Pero esto no se compila correctamente. Se muestran varios errores, incluyendo:

1) Error de sintaxis en el componente de puntero de procedimiento

y

2) ''operator'' en (1) no es miembro de la estructura ''type_a''

Además de algunas declaraciones de uso sin éxito. ¿Hay alguna manera de hacer esto correctamente? Cualquier ayuda es muy apreciada.

ACTUALIZAR:

He modificado el procedure,pointer a procedure(),pointer y ahora los errores son

1) El atributo FUNCTION entra en conflicto con el atributo SUBROUTINE en ''operator''

y

2) No se puede convertir DESCONOCIDO en INTEGER (4)

Ambos se refieren a la línea x = A%operator(y,z)


Como ha descubierto, la sintaxis para declarar una declaración de puntero de procedimiento requiere procedure([interface]), pointer [, ...] :: ... Usted eligió procedure(), pointer, nopass :: operator .

La consecuencia del procedure() es que no está declarando si el operator es una función o una subrutina. No hay nada de malo en esto, pero luego queda más trabajo en convencer al compilador de que está utilizando las referencias de manera consistente. Parece que tu compilador no te cree.

En lugar de entrar en detalles de lo que el compilador cree que quiere decir, tomaré un enfoque diferente.

Hace referencia al A%operator para una estructura A de tipo con ese componente como resultado de la función de operate . Usted dice claramente al declarar esta última función que su resultado es un número entero.

Ahora, suponiendo que no quiere hacer cosas emocionantes con la conversión tipo / tipo para llegar a ese resultado entero, consideraremos que siempre tiene la intención de que A%operator sea ​​una función con un resultado entero. Eso significa que puede declarar que el componente de puntero a procedimiento es una función con resultado entero.

Esto todavía te deja con opciones:

type type_A procedure(integer),pointer,nopass :: operator end type

siendo una función con resultado entero e interfaz implícita, y

type type_A procedure(add),pointer,nopass :: operator end type

siendo una función con interfaz explícita que coincide con la función add .

Sus opciones de diseño en curso informan su decisión final.

Como nota final, no está utilizando implicit none . Esto es importante cuando consideramos su línea

external :: operator

Si el operator es una función, entonces (por reglas implícitas de tipado) tiene un resultado real (predeterminado). Entonces, quiere cambiar a uno de los siguientes

integer, external :: operator

o

procedure(integer) :: operator

o

procedure(add) :: operator

Para concluir, y hacerse eco del comentario de Vladimir F, piense detenidamente en su diseño. Actualmente tiene restricciones de la referencia de operate (en el resultado de la función y sus argumentos) que parece que realmente sabe que el componente tendrá una interfaz específica. Si está seguro de eso, entonces use el procedure(add) como la declaración /