问题描述
我想编程一些适用于不同类型的程序。我打算使用描述的flib中使用的include方法和。我在这里给出一个简单的例子。
! -------------------------------------------------- ------------!
模块data_type
类型ivalue
整数:: v
结束类型
类型rvalue
real(8):: v
结束类型
结束模块data_type
! -------------------------------------------------- ------------!
模块imod
仅使用data_type:T => ivalue
包含template.f90
结束模块imod
! -------------------------------------------------- ------------!
模块rmod
仅使用data_type:T =>右值
包含template.f90
最终模块rmod
! -------------------------------------------------- ------------!
模块mod
使用imod,仅:
& ivalue => T,
& iprintme => printme
使用rmod,仅:
& rvalue => T,
& rprintme => printme
private
public :: ivalue,rvalue
public :: printme
接口printme
模块过程iprintme
模块procedure rprintme
end interface printme
end module mod
! -------------------------------------------------- ------------!
程序hello
使用mod
隐含无
类型(ivalue):: iv
类型(右值): :rv
iv%v = 42
rv%v = 3.14
致电printme(iv)
致电printme(rv)
结束程序hello
包含文件:
子程序printme(a)
隐含无
类型(T ):: a
$ b print *,a
结束子程序printme
令我困扰的是,它似乎只适用于派生类型,而不适用于内在类型。如果模块mod的用户想要在一个简单的整数上使用printme例程,他真的很烦人,因为他把它封装在一个ivalue类型中,并且不能这样做:
integer :: a = 42
call printme(a)
有没有什么方法可以将此方法扩展到内部类型,或者另一种方法可以在严格的f90 / f95中执行(由于数据拷贝,我不想使用传输方法)
坦克!
您可以在所有专业中使用C预处理器Fortran编译器。通常会有一个标志来调用它(gfortran中的 -cpp
),或者如果文件后缀包含大写字母F( .F90
,
.F
)。预处理器允许使用宏更强大地包含源代码。
module imod
use data_type ,仅:ivalue
#define T类型(ivalue)
#includetemplate.f90
#undef T
结束模块imod
模块intmod
#define T整数
#includetemplate.f90
#undef T
end module intmod
和template.f90
<$ $ a
$
print *,a
结束子程序printme
这是不是严格的f90 / f95,但它使用了包含在编译器中的预处理器,它生成另一个(严格的f95)源文件,并自动编译它,而不是包含宏的原始源文件。 p>
编译过程很简单
gfortran -cpp main.f90
- 编辑 -
对于非信徒,如果您想使用此功能查看一些真实的代码,请查看(免责声明:我自己的代码)。您可以在那里使用参数化链表:
len(20)字符串列表:
<$ p $模块str_list
#define TYPEPARAM字符(20)
#includelist-inc-def.f90
包含
#includelist-inc-proc.f90
#undef TYPEPARAM
结束模块
整数列表
模块int_list
#define TYPEPARAM整数
#includelist-inc-def.f90
包含
#includelist-inc-proc.f90
#undef TYPEPARAM
结束模块
某些派生类型的列表
module new_type_list
use,new_type_module,only:new_type
#define TYPEPARAM type(newtype)
#includelist-inc- def.f90
包含
#includelist-inc-proc.f90
#undef TYPEPARAM
结束模块
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
with the included file:
contains
subroutine printme(a)
implicit none
type(T) :: a
print *,a
end subroutine printme
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)
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)
Tanks!
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
and template.f90
contains
subroutine printme(a)
implicit none
T :: a
print *,a
end subroutine printme
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.
The compilation is then straightforward
gfortran -cpp main.f90
--Edit--
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:
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
list of integers
module int_list
#define TYPEPARAM integer
#include "list-inc-def.f90"
contains
#include "list-inc-proc.f90"
#undef TYPEPARAM
end module
list of some derived type
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中使用内部类型进行一些泛型编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!