0

考虑以下示例代码:

module mod

implicit none

type :: typeBase1
    integer :: A1
end type

type :: typeBase2
    integer :: A3
end type

type :: typeBase3
    integer :: A3
end type

type, extends(typeBase1) :: typeDerived1
    ! Void
end type

type, extends(typeBase2) :: typeDerived2
    ! Void
end type

type, extends(typeBase3) :: typeDerived3
    ! Void
end type

type, extends(typeBase1) :: typeDerived11        
    ! Void
end type

type, extends(typeBase2) :: typeDerived21
    ! Void
end type

type, extends(typeBase3) :: typeDerived31
    ! Void
end type


type :: complexType
   class(typeBase1), pointer :: ptrBase1  ! typeBase1, 2 and 3 are extensible
   class(typeBase2), pointer :: ptrBase2
   class(typeBase3), pointer :: ptrBase3
end type

interface calcul
    subroutine calculA(obj1, obj2, obj3)
        import
        type(typeDerived1) :: obj1        ! typeDerived 1, 2 et 3 are derived type of typeBase1, 2 and 3 
        type(typeDerived2) :: obj2
        type(typeDerived3) :: obj3
    end subroutine
    subroutine calculB(obj1, obj2, obj3)
        import
        type(typeDerived11) :: obj1        ! typeDerived 11, 21 et 31 are derived type of typeBase1, 2 and 3 
        type(typeDerived21) :: obj2
        type(typeDerived31) :: obj3
    end subroutine
end interface calcul

contains

    subroutine calculComplexType(complex)
        type(ComplexType), intent(inout) :: complex

        call calcul(complex % ptrBase1, complex % ptrBase2, complex % ptrBase3)
    end subroutine

end module mod

我想做的是子程序calculComplexType调用不同版本的子程序calcul,基于ptrBase1、ptrBase2和ptrBase3的动态类型。

该代码不起作用,因为编译器会查找具有以下接口的子例程:

subroutine calcul(obj1, obj2, obj3)
    class(typeBase1) :: obj1         
    class(typeBase1) :: obj2
    class(typeBase1) :: obj3
end subroutine

无论 ptrBase1、ptrBase2 和 ptrBase3 的动态类型是什么。

我的问题是:在 Fortran 中有没有办法编写接口计算,以便根据参数的动态类型自动选择一个过程?

我想避免使用长序列的“选择类”。

欢迎任何重写代码的建议!

4

2 回答 2

1

如果您根据所有三个参数请求调度,则无法完成。一些语言为此提供了所谓的方法。

在 Fortran 中,您可以使用普通的单一调度方法(类型绑定过程),但在这种情况下,它只能根据一个参数选择子例程。

否则,您必须使用select 类型构造并case为每个可能的组合创建一个,无论是在一个过程中,还是在它的多个版本之间进行选择。

对于两个参数,您还可以考虑双分派模式

于 2013-09-24T13:21:15.217 回答
0

这在 Fortran 中根本不可能;使用多态性可以做的最好的事情是使用重写的类型绑定过程,根据一个特定实体的动态类型选择一个函数。

但是,根据所做操作的性质,只定义一个采用多态参数(即, , )的版本并处理其内部的动态类型calcul可能更有意义。好处是双重的:calculclass(typeBase1)class(typeBase2)class(typeBase3)calcul

  1. calcul可能能够独立于其他参数测试每个参数的类型。如果是这种情况,您仍然需要编写三个select type构造,但它们不会嵌套或重复。

  2. 您很可能可以使用单次分派(使用类型绑定过程)来select type完全消除对构造的需求。

我很难想到这个问题中的代码确实是您可以使用的最佳设计。

如果calcul真的为每个动态类型做一些完全“不同”的事情,以一种与调用它的代码相关的方式,那么调用代码不应该使用多态指针(例如complexType,每个不同的指针可能应该有一个不同的指针calcul)。

但是,如果每个版本calcul基本上都在做“相同”的操作(就更高级别的代码知道/关心的而言),无论动态类型如何,那么应该只有一个版本,它应该接受基类的参数.

于 2013-09-25T02:49:51.567 回答