fortran - 不同等级的重载fortran接口(interface)

标签 fortran overloading rank

在 Fortran 模块中,我有一个函数,它接受一个数组及其名称,从数据库(实际上调用一个 C 函数)获取数组的形状,将数组复制到临时缓冲区中并将缓冲区传递给另一个 C 函数来处理它。此 Fortran 函数的名称为 fs_WriteData_i(用于整数数据)、fs_WriteData_f(用于实数)和 fs_WriteData_d(用于 double )。所有这些函数不仅接受一维数组,还接受 2D、3D 和 4D 数组,并且它们工作得很好。下面是这些子例程之一的接口(interface):

subroutine fs_WriteData_d(fieldname, data)
    use, intrinsic :: iso_c_binding
    implicit none

    real(c_double), dimension(*) :: data
    character                    :: fieldname*(*)

    ! ...

end subroutine fs_WriteData_d

如果用户调用fs_WriteData_d('name', data)数据是 double 的,最多 4 维数组,这个子程序可以完成这项工作。

现在,问题是:我想提供一个名为 fs_WriteData 的通用重载接口(interface),所以我使用
interface fs_WriteData
    module procedure fs_WriteData_i, &
                     fs_WriteData_f, &
                     fs_WriteData_d
end interface fs_WriteData

不幸的是,这不起作用:编译器指出如果用户只是调用 fs_WriteData('name', data),它将找不到正确的实现。 ,这是因为与所有这些函数的排名不匹配。

是否有一种巧妙的方法可以避免编写所有 fs_WriteData_d_1d、fs_WriteData_d_2d、... 子程序的内容相同,从而使模块更易于维护?

提前谢谢了。

最佳答案

有点。

正如您所发现的,从 F2008 开始,为通用调用选择特定过程的规则除其他事项和基本过程外,还需要类型、种类和等级的匹配(所谓的 TKR 兼容)。即使假设数据虚拟参数的大小(因此在直接调用特定过程时,它可以与任何非零等级的实际参数相关联),出于 TKR 兼容性的目的,它仍然被视为等级一的参数。

最近发布的关于 Fortran 与 C 的进一步互操作性的技术规范 (TS29113) 增加了假定等级的概念。取决于您在 fs_WriteData_d 的可执行部分中所做的事情(传递给 C 几乎是你能做的所有事情)可能适合 - 类型/种类/等级匹配的规则已经扩展,使得假定等级实际或虚拟参数是兼容的,无论等级如何。相当重要的问题是编译器支持——我认为目前没有任何编译器支持这个 TS!

对于 F201X 之前的语言标准编码,有几种可能性:

  • 为您想要支持的每个等级编写一系列瘦包装子例程,然后这些包装子例程调用一维形式的特定过程,依靠序列关联将多维数组映射到一维数组。
  • 将子程序的主体放在一个单独的文件中,并将该文件包含在每个等级的子程序的骨架接口(interface)中。这种方法要求子程序主体内的代码在词法上是独立的。在某些情况下,代码也可以以独立于类型的方式编写,您可以使用一个通用的包含文件来处理您想要支持的各种类型。虽然这消除了与“复制和粘贴”代码的更改管理相关的问题,但处理 INCLUDE 文件可能有点痛苦。

  • 两者的某种组合也可能是合适的。

    (可能存在第三种选择,使用 C 互操作性将为每个等级和类型组合编写的接口(interface)主体的绑定(bind)名称设置为一个实现过程的绑定(bind)名称,但我不确定 C 的(ab)用法是否互操作性是合法的。)

    如果您所追求的只是不同类型变体的通用命名,那么另一种可能性(再次取决于您在正文中执行的操作)是将数据参数作为 ISO_C_BINDING 内部模块中的 C_PTR 并插入采取的要求将实际参数的 C_LOC 返回到子例程的客户端代码中。

    关于fortran - 不同等级的重载fortran接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14434293/

    相关文章:

    php - 我如何修改此 MySQL 查询来查找排名?

    java - 如何将 Fortran 代码与 Java GUI 集成?

    Fortran 4.7.2/4.8.1 错误 : There is no specific subroutine for the generic 'vode' at (1)

    c++ - 特化和重载有什么区别

    带有抽象参数的Java泛型接口(interface)调用

    delphi - Delphi 中函数重载有运行时开销吗?

    php - 如何使用 PHP 函数更有效地获取表中多列的排名

    Fortran 90 存在可选参数

    c++ - 增加 mpi 中的 CPU 数量会增加处理时间?

    ranking - 投票算法: how to calculate rank?