在Fortran中,有没有办法确定变量的类型?
需要变量类型的可能用例如下。我们将变量的类型作为参数传递给函数,以便能够使用该函数调用特定于类型的代码,从而无需为每种数据类型分别使用相似的函数。
答案 0 :(得分:8)
如果你搞乱了KIND内在函数和指针,你可能能够做你想做的事情,但是如果你只关心函数和子程序的签名,那就把它留给Fortran吧。如果你定义
function calc8(arg1)
real(8), intent(in) :: arg1
...
和
function calc4(arg1)
real(4), intent(in) :: arg1
...
在一个模块中,并声明一个像这样的接口
interface calc
module procedure calc8
module procedure calc4
end interface
(警告,我没有详细检查语法,这是你的责任。)
然后Fortran会将调用与正确版本的函数匹配。当然,你必须编写该函数的两个版本,但这确实是Fortran 95的做法。这可能非常繁琐,我倾向于编写通用版本并运行sed脚本来专门化它。这有点像kludge,但它确实有效。
如果函数的代码与参数的类型相同,我有时会为real(8)(或其他)编写函数,并为real(4)编写一个调用真实(8)版本的版本在类型转换中。
在Fortran 2003中,有一些改进的方法来定义多态和泛型函数,但我还没有真正理解它们。
答案 1 :(得分:4)
是的,有两种方式。
第一种方法要求您为每个变量类型编写单独的函数或子例程,但不必调用不同的函数。这可能会或可能不会足够接近您想要的。编写单独的例程,然后编写一个接口来创建包含这些特定子例程的泛型函数或子例程。您不必传递变量类型,也不必在调用中执行任何特殊操作 - 只需通过变量本身由编译器自动完成,只要变量足够不同以便编译器可以区分他们(有关于所需要的规则)。这与内部函数的工作方式类似 - 您可以使用实参,双精度实参或复参数调用sin,编译器调用正确的实际函数并返回匹配结果。高性能标志沿着这些方针勾勒出了一个解决方案。对于另一个问题,我发布了一个工作示例,其中变量的区别特征是数组排名:how to write wrapper for 'allocate'。这种方法的一个优点是它得到了Fortran编译器的广泛支持。
在Fortran 2003/2008中,有广泛的面向对象功能。引用Metcalf,Reid和Cohen的“Fortran 95/2003解释”,“为了根据多态实体的动态类型执行替代代码并获得对动态部分的访问,选择类型构造是提供。” select type 语句有点类似于 select case 语句。这是少数编译器的支持。同样,您不必传递类型,因为编译器可以从变量本身中找到它。但它必须是一个多态类型... Intel ifort和gfortran列表选择支持的类型和多态数据类型 - 后者在gfortran(http://gcc.gnu.org/wiki/Fortran2003)中有一些实验方面。这些是最近对这些编译器的补充。