subrutinas subprogramas guia funciones ejemplos arcoseno fortran fortran95 fortran2003

subprogramas - declaración de clase fortran de argumento ficticio



guia fortran (2)

Me gustaría tener un tipo derivado, a , que está vacío. De este tipo derivado me gustaría definir más tipos que amplíen a. Supongamos que todas estas extensiones de tipo contienen algún nombre generic procedimiento, value , es decir, value => valuea1 , value => valuea2 , etc.

Si luego quiero pasar las variables de la clase a a algún otro procedimiento, necesito declarar el argumento ficticio relevante de ese procedimiento con la class(a) . Sin embargo, si hago esto, hacer referencia al value del argumento ficticio conduce a la falla de compilación porque la clase a está realmente vacía, solo las extensiones de tipo contienen el procedimiento.

Podría prescindir de esto teniendo algún procedimiento llamado value dentro de la definición de tipo de a (luego anulando en las extensiones). Sin embargo, dado que nunca quiero declarar ningún objeto con el tipo a, parece desordenado. Es posible evitar esto?


Sí, puede declarar un procedimiento enlazado por tipo incluso para un tipo abstract . Puede ser un procedimiento enlazado de tipo real, o simplemente una abstract interface .

type, abstract :: a contains procedure :: valuea1, valuea2 generic value :: value => valuea1, valuea2 end type abstract interface ! the headers of valuea1, valuea2 here ! they should have a passed dummy argument class(a) ! and some other argument for the generic resolution ! for example: subroutine valua1(self, x) class(a), intent(in) :: self real, intent(inout) :: x end subroutine subroutine valua2(self, x) class(a), intent(in) :: self integer, intent(inout) :: x end subroutine end interface

De esta forma, no puede crear variables de type(a) , pero puede crear tipos extendidos que implementen sus propias versiones de value .


Similar a la respuesta de @VladimirF, pero tomando su aclaración de que

Realmente no necesito la resolución genérica; valuea1 y valuea2 aceptan el mismo tipo de argumentos para el problema que tengo en mente, solo quiero vincularme a valuea1 en una extensión de tipo y a valuea2 en otra extensión de tipo.

Aquí, entonces, el tipo base (abstracto) define un value() procedimiento de límite de tipo diferido value() con una class(a) toma de interfaz class(a) como el argumento pasado. Se pueden agregar otros argumentos. Cada tipo de extensión define / anula este procedimiento de tipo vinculado con su propio procedimiento.

Esto significa que en nuestra test_sub subrutina final test_sub el argumento ficticio de class(a) tiene un %value() .

module types ! The base type type, abstract :: a contains procedure(value_if), deferred :: value end type a ! The interface for the type-bound procedures abstract interface subroutine value_if(var) import a class(a) var end subroutine value_if end interface ! The extending types, overriding the value subroutine type, extends(a) :: a1 contains procedure :: value => value_a1 end type a1 type, extends(a) :: a2 contains procedure :: value => value_a2 end type a2 contains subroutine value_a1(var) class(a1) var print*, "Value of a1" end subroutine value_a1 subroutine value_a2(var) class(a2) var print*, "Value of a2" end subroutine value_a2 end module types program test use types type(a1) x type(a2) y call x%value call y%value call test_sub(x) call test_sub(y) contains subroutine test_sub(var) class(a) var call var%value ! This is defined end subroutine test_sub end program test

Esto produce salida

Valor de a1
Valor de a2
Valor de a1
Valor de a2