fortran - 如何在 fortran 90/95 中使用内部类型进行一些通用编程

标签 fortran fortran90 generic-programming fortran95

我想编写一些适用于不同类型的程序。我计划使用在 here 描述的 flibs 中使用的“包含”方法和 here .我在这里举一个简单的例子。

  ! -------------------------------------------------------------- ! 
  module data_type

  type ivalue
  integer :: v
  end type

  type rvalue
  real(8) :: v
  end type

  end module data_type
  ! -------------------------------------------------------------- ! 
  module imod

  use data_type, only: T => ivalue 

  include "template.f90"

  end module imod
  ! -------------------------------------------------------------- ! 
  module rmod

  use data_type, only: T => rvalue 

  include "template.f90"

  end module rmod
  ! -------------------------------------------------------------- ! 
  module mod

  use imod, only:
 &     ivalue => T,
 &     iprintme => printme

  use rmod, only:
 &     rvalue => T,
 &     rprintme => printme

  private
  public :: ivalue, rvalue
  public :: printme

  interface printme
  module procedure iprintme
  module procedure rprintme
  end interface printme

  end module mod
  ! -------------------------------------------------------------- !
  program hello

  use mod

  implicit none

  type(ivalue) :: iv
  type(rvalue) :: rv

  iv%v=42
  rv%v=3.14

  call printme(iv)
  call printme(rv)      

  end program hello

使用包含的文件:
  contains

  subroutine printme(a)

  implicit none

  type(T) :: a

  print *,a

  end subroutine printme

困扰我的是它似乎只适用于派生类型,而不适用于内在类型。如果模块 mod 的用户想要在一个简单的整数上使用 printme 例程,那么将它封装在 ivalue 类型中对他来说真的很烦人并且不能这样做:
integer :: a=42
call printme(a)

有没有办法将此方法扩展到内在类型,或者另一种方法可以在严格的 f90/f95 中执行(由于数据复制,我不想使用“传输”方法)

坦克!

最佳答案

您可以在所有主要的 Fortran 编译器中使用 C 预处理器 (CPP)。通常有一个标志用于调用它(-cpp 在 gfortran 中),或者如果文件后缀包含大写 F(.F90.F),它会自动调用。预处理器允许使用宏来更强大地包含源。

module imod

  use data_type, only: ivalue 

#define T type(ivalue)
#include "template.f90"
#undef T

end module imod


module intmod

#define T integer
#include "template.f90"
#undef T

end module intmod

和模板.f90
contains

subroutine printme(a)

  implicit none

  T :: a

  print *,a

end subroutine printme

这不是严格的 f90/f95,但它使用编译器中包含的预处理器,生成另一个(严格的 f95)源文件,它会自动编译它而不是包含宏的原始源文件。

然后编译很简单
gfortran -cpp main.f90

--编辑--

对于非信徒,如果你想看到一些使用它的真实代码,请查看 https://github.com/LadaF/fortran-list (免责声明:我自己的代码)。您可以将参数链表用作:

len(20) 字符串列表:
module str_list

#define TYPEPARAM character(20)

#include "list-inc-def.f90"
contains
#include "list-inc-proc.f90"
#undef TYPEPARAM
end module

整数列表
module int_list

#define TYPEPARAM integer

#include "list-inc-def.f90"
contains
#include "list-inc-proc.f90"
#undef TYPEPARAM
end module

一些派生类型的列表
module new_type_list
  use, new_type_module, only: new_type

#define TYPEPARAM type(newtype)

#include "list-inc-def.f90"
contains
#include "list-inc-proc.f90"
#undef TYPEPARAM
end module

关于fortran - 如何在 fortran 90/95 中使用内部类型进行一些通用编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24064633/

相关文章:

file-io - 打开第 5 或 6 单元上的文件

fortran - 正确设置随机种子以实现可重复性

parallel-processing - OpenMP 在线程中调用子程序

Fortran 2003 不允许此内部过程 [BESSEL_J0]

types - Fortran: 'select type'子句中​​的参数化派生类型

java - 具有包含泛型类本身引用的数组列表的泛型类

vb.net - 如何使 VB.NET 函数的参数作为泛型类型?

arrays - fortran 中的数组数组

pointers - 比较两个指针

ios - 通用函数 -> 无法将返回表达式转换为返回类型