Module 如何在Fortran中使用子模块实现通用接口?

Module 如何在Fortran中使用子模块实现通用接口?,module,fortran,procedure,gfortran,Module,Fortran,Procedure,Gfortran,我的问题是,我有两个通用过程,分别在“mod1.f08”和“mod2.f08”中实现 ! mod1.f08 MODULE mod1 INTERFACE func1 procedure :: foo_int, foo_real ... ! mod2.f08 MODULE mod2 INTERFACE func2 procedure :: bar_int, bar_real ... 但我想以一个模块的子模块的形式连接这两个模块,方法如下: ! mod1.f

我的问题是,我有两个通用过程,分别在“mod1.f08”和“mod2.f08”中实现

! mod1.f08
MODULE mod1

   INTERFACE func1
      procedure :: foo_int, foo_real
...

! mod2.f08
MODULE mod2

   INTERFACE func2
      procedure :: bar_int, bar_real
...
但我想以一个模块的子模块的形式连接这两个模块,方法如下:

! mod1.f08
MODULE (mainmodule) mod1

   INTERFACE func1
      procedure :: foo_int, foo_real
...

! mod2.f08
MODULE (mainmodule) mod2

   INTERFACE func2
      procedure :: bar_int, bar_real
...

! mainmodule.f08
MODULE mainmodule

    INTERFACE
       procedure :: func1
       procedure :: func2
    END INTERFACE
    ...

这样做可能吗?

这就是你想要实现的目标吗

module Main_mod

    interface
    module subroutine foo(dummyReal)
        real, intent(in) :: dummyReal
    end subroutine foo
    end interface

    interface
    module subroutine bar(dummyInt)
        integer, intent(in) :: dummyInt
    end subroutine bar
    end interface

    interface genericFunc
        module procedure :: foo, bar
    end interface genericFunc

end module Main_mod

submodule (Main_mod) SubMain1_smod
contains
    module subroutine foo(dummyReal)
        real, intent(in) :: dummyReal
        write(*,"(*(g0,:,' '))") "This is from inside foo @SubMain1_smod: dummyReal = ", dummyReal
    end subroutine foo
end submodule SubMain1_smod

submodule (Main_mod) SubMain2_smod
contains
    module subroutine bar(dummyInt)
        integer, intent(in) :: dummyInt
        write(*,"(*(g0,:,' '))") "This is from inside bar @SubMain2_smod: dummyInt = ", dummyInt
    end subroutine bar
end submodule SubMain2_smod

program hello
    use Main_mod, only: genericFunc
   call genericFunc(1.)
   call genericFunc(1)
end program Hello
下面是一个测试输出:

> ifort main.f90 -o run.exe
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.4.245 Build 20190417
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.22.27905.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:run.exe
-subsystem:console
main.obj

> run.exe
This is from inside foo @SubMain1_smod: dummyReal =  1.000000
This is from inside bar @SubMain2_smod: dummyInt =  1
通用过程的接口必须位于主模块中,而实现则位于子模块中。如果过程实现太大,我会将子模块与主模块分开,并将它们放在单独的文件中。如果只对子模块而不是主模块中的接口进行任何更改,这也将避免通过
make
软件进行编译级联。(我通常对任何子模块大小都这样做)。如果过程接口也太大(有太多的伪输入/输出参数),也可以通过子模块中的
procedure
关键字避免每个过程的重复接口(一次在主模块中,另一次在过程实现的子模块中),如下所示:

module Main_mod

    interface
    module subroutine foo(dummyReal)
        real, intent(in) :: dummyReal
    end subroutine foo
    end interface

    interface
    module subroutine bar(dummyInt)
        integer, intent(in) :: dummyInt
    end subroutine bar
    end interface

    interface genericFunc
        module procedure :: foo, bar
    end interface genericFunc

end module Main_mod

submodule (Main_mod) SubMain1_smod
contains
    module procedure foo
        write(*,"(*(g0,:,' '))") "This is from inside foo @SubMain1_smod: dummyReal = ", dummyReal
    end procedure foo
end submodule SubMain1_smod

submodule (Main_mod) SubMain2_smod
contains
    module procedure bar
        write(*,"(*(g0,:,' '))") "This is from inside bar @SubMain2_smod: dummyInt = ", dummyInt
    end procedure bar
end submodule SubMain2_smod

program hello
    use Main_mod, only: genericFunc
   call genericFunc(1.)
   call genericFunc(1)
end program Hello

这将生成相同的二进制文件,但实现较短。但是,我个人不喜欢它,因为它经常要求您查看父模块(通常位于单独的文件中)以获取任何伪参数信息。我希望我正确理解了您的问题。

您能更具体地说明您的问题吗?通常的方法是将
接口
信息放在一个文件中的模块中,将子模块中的实现细节放在另一个文件中。我只想使用子模块来连接一些通用过程,这些过程非常庞大,只能放在一个或两个文件中。但正如您在上一段代码中所显示的,要处理所有过程并创建泛型过程,这很复杂。我的想法是在单独的子模块上创建通用过程,以便只在一个模块上连接。另一种选择是在带有“use”子句的主模块上包含具有此通用过程的模块。它要简单得多,但我不认为舒尔是理想的。我相信这是最简单的。更简洁的解决方案是将所有例程放在一个父模块中,避免父模块和子模块的接口重复。如果两个例程的实现是相同的,您还可以将实现合并到单个文件中,并在模块中需要它们的地方包含它们的实现,但这既丑陋又有潜在的危险。我不认为在任何其他低级语言(包括C/C++)中有比Fortran更简单的解决方案。