在Fortran中将以派生类型为参数的函数作为参数传递

3

我有一个子程序,接受一些数据和另一个函数作为参数。该函数可以将此数据作为参数。子程序只是用给定的数据调用此函数。现在假设数据可以是类型foo。我认为我也可以传递衍生类型bar的数据。但是Fortran显然不同意。

我尝试使用gfortran 9编译下面的代码,但它失败了并显示以下错误消息:

   47 |         call funA(x, y, baz)
      |                        1
Error: Interface mismatch in dummy procedure ‘baz’ at (1): Type mismatch in argument 'y' (CLASS(foo)/CLASS(bar))

尝试用bar替换foo的其他尝试也产生了类似的结果。使用pgfortran 19.4会导致相同的错误。

module A
    implicit none
    private

    type, abstract, public :: foo
    end type foo

    public :: funA

contains

    subroutine funA(x, y, baz)
        integer, intent(in)    :: x
        class(foo), intent(in) :: y
        interface
            function baz(x, y) result(z)
                import foo
                integer,    intent(in) :: x
                class(foo), intent(in) :: y
                integer                :: z
            end function baz
        end interface

        write(*,*) baz(x, y)
    end subroutine funA

end module

module B
    use A
    implicit none
    private

    type, extends(foo), public :: bar
        integer :: ii
    end type bar

    public :: fiz

contains

    function baz(x, y) result(z)
        integer,    intent(in) :: x
        class(bar), intent(in) :: y
        integer :: z

        z = x + y%ii
    end function baz

    subroutine fiz(x, y)
        integer,    intent(in) :: x
        class(bar), intent(in) :: y

        call funA(x, y, baz) ! <---- This causes errors.
    end subroutine fiz
end module

program meh
    use B
    implicit none
    integer   :: x
    type(bar) :: y
    x = 1
    y%ii = 2
    call fiz(x, y)
end program meh

我的期望是,由于y的类型为bar,也应该是foo类型,因此我可以将其传递给funA。函数baz必须知道y是bar类型,否则它无法访问ii。但是代码的其余部分似乎并不需要知道这一点,对吗?
我的推理哪里出错了?如何使上述代码编译并运行?
1个回答

3
这里指出的错误在于过程参数的特征。函数funA的过程虚拟参数baz具有与模块B的过程实际参数baz不匹配的特性。虚拟参数的第二个参数(y)是声明类型为foo,而传递给它的baz过程相应的参数是声明类型为bar
虚拟和实际过程参数的特性不允许存在这种不匹配。
要解决此问题,必须将虚拟baz和模块过程baz的虚拟参数y的类型更改为相同的声明类型(可能是foo)。当然,然后需要处理baz中的y(模块B中),其声明类型为foo:这样的y没有组件ii。一个快速的解决方法是使用select type结构,但如果可以设计不同的流程,则可能会有其他方法。
正如您所看到的,通常像这样的代码讨论会受到不同名称的各种参数等的帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接