我检查了类似的问题和相关的教科书,但找不到解决这个问题的方法。
注意:这是使用现代 Fortran。
所以,我想要一个基类型,例如base
,它包含一个类型绑定过程,例如run
,它委托给扩展基类型的子例程,例如type, extends(base) :: my_extension
。让我们调用我们希望委托给的子例程my_procedure
。
我可以通过一种相当复杂的方式来实现这一点,方法是base
抽象化,base
包含一个延迟的过程,例如delegate
,run
委托给delegate
,然后实现delegate
并my_extension
让它委托给my_procedure
。
但是,这很麻烦,因为它需要扩展base
来实现的类型,delegate
但所有实现都只是简单地委托给其他一些过程。由于我通常需要多个实例my_extension
,每个实例在其中委托给不同的过程,这使情况变得更加复杂my_extension
,在这种情况下,我需要在那里保持my_extension
抽象、扩展my_extension
和实现delegate
,因此我最终得到的扩展与我拥有的过程一样多!
所以,我想知道是否有使用过程指针或类似的更清洁的方法。我想要的是这样的东西......
base.f90:
module base_mod
implicit none
type base
procedure(my_interface), pointer :: ptr ! Pointer component
contains
procedure :: run ! Type-bound procedure
end type base
abstract interface
subroutine my_interface(self)
import :: base
class(base) :: self ! This is a problem...
end subroutine my_interface
end interface
contains
subroutine run(self)
class(base) :: self
call self%ptr()
end subroutine run
end module base_mod
my_extension.f90:
module my_extension_mod
use base_mod
implicit none
type, extends(base) :: my_extension
contains
procedure :: my_procedure
end type my_extension
contains
subroutine my_procedure(self)
class(my_extension) :: self ! ...because this is different.
! Do useful stuff, e.g.
print *, "my_procedure was run"
end subroutine my_procedure
end module my_extension_mod
main.f90:
program main
use my_extension_mod
implicit none
type(my_extension) :: my_instance
procedure(my_interface), pointer :: my_ptr
my_ptr => my_procedure
my_instance = my_extension(my_ptr) ! Use implicit constructor
call my_instance%run() ! Expect to see "my_procedure was run" printed
end program main
使.sh:
#! /bin/bash
gfortran -c base.f90
gfortran -c my_extension.f90
gfortran base.o my_extension.o main.f90
但是,编译器抱怨如下:
main.f90:9.14:
my_ptr => my_procedure
1
Error: Interface mismatch in procedure pointer assignment at (1): Type/rank mismatch in argument 'self'
这是因为my_interface
期望类的对象base
作为输入,而my_procedure
将类的对象my_extension
作为输入,因此从技术上讲接口不匹配。但是,my_extension
扩展base
所以,在某种程度上,这应该是可以的(但就编译器而言显然不是可以的)。
所以,我的问题是:我怎样才能克服这个问题?我怎样才能拥有一个适用于my_procedure
但仍适用于其他扩展类型的其他过程base
(例如 中的那些my_other_extension
)的接口?或者如何在base
不使用接口的情况下获得指向扩展程序的指针?或者我怎样才能实现我正在尝试做的其他方式(例如不使用指针)但仍然避免顶部描述的混乱抽象类型方法?