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

问题描述 投票:1回答:1

我的问题是,我在'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 fortran procedure gfortran
1个回答
0
投票

这是您打算实现的目标吗?

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

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

© www.soinside.com 2019 - 2024. All rights reserved.