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

jan*_*195 4 fortran generic-programming fortran90 fortran95

我想编写一些适用于不同类型的程序.我打算使用这里这里描述的flibs中使用的"include"方法.我在这里给出一个简单的例子.

  ! -------------------------------------------------------------- ! 
  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
Run Code Online (Sandbox Code Playgroud)

使用包含的文件:

  contains

  subroutine printme(a)

  implicit none

  type(T) :: a

  print *,a

  end subroutine printme
Run Code Online (Sandbox Code Playgroud)

困扰我的是它似乎只适用于派生类型,而不适用于内在类型.如果模块mod的用户想要在一个简单的整数上使用printme例程,那么将它封装在一个ivalue类型中并且无法执行以下操作真的很烦人:

integer :: a=42
call printme(a)
Run Code Online (Sandbox Code Playgroud)

有没有办法将此方法扩展为内部类型,或者在严格的f90/f95中执行此操作的另一种方法(由于数据复制,我不想使用"transfer"方法)

坦克!

Vla*_*r F 6

您可以在所有主要的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
Run Code Online (Sandbox Code Playgroud)

和template.f90

contains

subroutine printme(a)

  implicit none

  T :: a

  print *,a

end subroutine printme
Run Code Online (Sandbox Code Playgroud)

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

然后编译很简单

gfortran -cpp main.f90
Run Code Online (Sandbox Code Playgroud)

- 编辑 -

对于非信徒,如果你想看到一些使用它的真实代码,请查看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
Run Code Online (Sandbox Code Playgroud)

整数列表

module int_list

#define TYPEPARAM integer

#include "list-inc-def.f90"
contains
#include "list-inc-proc.f90"
#undef TYPEPARAM
end module
Run Code Online (Sandbox Code Playgroud)

一些派生类型的列表

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
Run Code Online (Sandbox Code Playgroud)