如何在 fortran 90/95 中使用内部类型进行一些通用编程 [英] How to make some generic programming in fortran 90/95 working with intrinsic types

查看:24
本文介绍了如何在 fortran 90/95 中使用内部类型进行一些通用编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一些适用于不同类型的程序.我打算使用 here这里.我这里举一个简单的例子.

I would like to program some procedure that will work with different types. I am planning to use the "include" method used in flibs described here and here. I give here a simple exemple.

  ! -------------------------------------------------------------- ! 
  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类型真的很烦人,不能这样做:

What bothers me is that it seems only to work with derived type, and not with intrinsic types. If the user of the module mod want to use the printme routine on an simple integer, it is really annoying for him to encapsulate it in a ivalue type and cannot doing:

integer :: a=42
call printme(a)

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

Is there any way to extend this method to intrinsic types, or another method that would do it in strict f90/f95 (I don't want to use the "transfer" method because of the data copy)

坦克!

推荐答案

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

You can use the C preprocessor (CPP) in all major Fortran compilers. Usually there is a flag for invoking it (-cpp in gfortran) or it is invoked automatically if the file suffix contains capital F (.F90, .F). The preprocessor allows more powerful inclusion of sources with the usage of macros.

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

和 template.f90

and template.f90

contains

subroutine printme(a)

  implicit none

  T :: a

  print *,a

end subroutine printme

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

This is not strict f90 / f95, but it uses a preprocessor, included in the compilers, which produces another (strict f95) source file and it automatically compiles it instead of the original source that contains the macros.

然后编译就很简单了

gfortran -cpp main.f90

--编辑--

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

For non-believers, if you want to see some real code using this, check https://github.com/LadaF/fortran-list (disclaimer: my own code). You can use the parametric linked list there as:

len(20) 字符串列表:

list of len(20) character strings:

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 90/95 中使用内部类型进行一些通用编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆