首页 > 解决方案 > 如何将 Fortran 过程指针作为派生类型的组件,该类型指向该类型扩展中的类型绑定过程?

问题描述

我检查了类似的问题和相关的教科书,但找不到解决这个问题的方法。

注意:这是使用现代 Fortran。

所以,我想要一个基类型,例如base,它包含一个类型绑定过程,例如run,它委托给扩展基类型的子例程,例如type, extends(base) :: my_extension。让我们调用我们希望委托给的子例程my_procedure

我可以通过一种相当复杂的方式来实现这一点,方法是base抽象化,base包含一个延迟的过程,例如delegaterun委托给delegate,然后实现delegatemy_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不使用接口的情况下获得指向扩展程序的指针?或者我怎样才能实现我正在尝试做的其他方式(例如不使用指针)但仍然避免顶部描述的混乱抽象类型方法?

标签: pointersfortranfortran2003derived-typesfortran2008

解决方案


推荐阅读