基于返回类型的Fortran泛型函数 [英] Fortran generic functions based on the return kind

查看:108
本文介绍了基于返回类型的Fortran泛型函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图根据要返回的值在Fortran中创建一个泛型函数,即,取决于该函数的输出是分配给单精度实数还是双精度实数.代码是:

I am trying to create a generic function in Fortran based on the value to be returned, that is, depending on if the output of the function is to be assigned to a single precision real or to a double precision real. The code is:

MODULE kk_M

   USE ISO_FORTRAN_ENV

   IMPLICIT NONE

   INTEGER, PARAMETER :: sp = REAL32
   INTEGER, PARAMETER :: dp = REAL64

   INTERFACE use_func
      MODULE PROCEDURE use_sp_func
      MODULE PROCEDURE use_dp_func
   END INTERFACE use_func

   INTERFACE use_sub
      MODULE PROCEDURE use_sp_sub
      MODULE PROCEDURE use_dp_sub
   END INTERFACE use_sub

   CONTAINS

   FUNCTION use_sp_func() RESULT(res)
      REAL(KIND=sp) :: res
      res = 5._sp
   END FUNCTION use_sp_func

   FUNCTION use_dp_func() RESULT(res)
      REAL(KIND=dp) :: res
      res = 5._dp
   END FUNCTION use_dp_func

   SUBROUTINE use_sp_sub(res)
      REAL(KIND=sp), INTENT(OUT) :: res
      res = 5._sp
   END SUBROUTINE use_sp_sub

   SUBROUTINE use_dp_sub(res)
      REAL(KIND=dp), INTENT(OUT) :: res
      res = 5._dp
   END SUBROUTINE use_dp_sub

END MODULE kk_M


PROGRAM kk
   USE kk_M
   IMPLICIT NONE
   REAL(KIND=sp) :: num_sp
   REAL(KIND=dp) :: num_dp

   num_sp = use_func()
   WRITE(*,*) num_sp

   num_dp = use_func()
   WRITE(*,*) num_dp

   CALL use_sub(num_sp)
   WRITE(*,*) num_sp

   CALL use_sub(num_dp)
   WRITE(*,*) num_dp

END PROGRAM kk

使用通用子例程,代码可以编译并运行,但是当我添加通用函数时,它不会编译.我使用gfortran收到以下错误消息:

With the generic subroutines the code compiles and works, but when I add the generic functions it does not compile. I get the following error message with gfortran:

kk.f90:22:3:

    FUNCTION use_sp_func() RESULT(res)                                                                                                                                             
   1
kk.f90:27:3:

    FUNCTION use_dp_func() RESULT(res)                                                                                                                                             
   2
Error: Ambiguous interfaces in generic interface 'use_func' for ‘use_sp_func’ at (1) and ‘use_dp_func’ at (2)
kk.f90:46:7:

    USE kk_M
       1
Fatal Error: Can't open module file ‘kk_m.mod’ for reading at (1): No existe el archivo o el directorio
compilation terminated.

看起来编译器无法根据要返回的值来区分这两个函数.有什么方法可以做到这一点?

It looks like the compiler cannot distinguish between both functions based on the value to be returned. Is there some way to achieve this?

推荐答案

按照弗拉基米尔F的建议,我看了一下传递固有函数,并在我的函数中添加了一个模具参数来设置返回类型.

Following the advice by Vladimir F, I had a look at the transfer intrisic function and added a mold parameter to my functions to set the return type.

如果函数的任何输入参数都是真实的,则可以使用它们将返回类型设置为High Performanceace Mark所述,但是由于这不是我的情况,因此我最终使用了模具变量.

If any input argument to the functions were real they could be used to set the return type as High Performace Mark stated, but since this is not my case I finally used the mold variable.

现在,它可以编译并工作了.代码是:

Now it compiles and work. The code is:

MODULE kk_M

   USE ISO_FORTRAN_ENV

   IMPLICIT NONE

   INTEGER, PARAMETER :: sp = REAL32
   INTEGER, PARAMETER :: dp = REAL64

   INTERFACE use_func
      MODULE PROCEDURE use_sp_func
      MODULE PROCEDURE use_dp_func
   END INTERFACE use_func

   INTERFACE use_sub
      MODULE PROCEDURE use_sp_sub
      MODULE PROCEDURE use_dp_sub
   END INTERFACE use_sub

   CONTAINS

   FUNCTION use_sp_func(mold) RESULT(res)
      REAL(KIND=sp),INTENT(IN) :: mold
      REAL(KIND=sp) :: res
      IF (.FALSE.) res = mold !To avoid compilation warning about unused variable
      res = 5._sp
   END FUNCTION use_sp_func

   FUNCTION use_dp_func(mold) RESULT(res)
      REAL(KIND=dp),INTENT(IN) :: mold
      REAL(KIND=dp) :: res
      IF (.FALSE.) res = mold !To avoid compilation warning about unused variable
      res = 5._dp
   END FUNCTION use_dp_func

   SUBROUTINE use_sp_sub(res)
      REAL(KIND=sp), INTENT(OUT) :: res
      res = 5._sp
   END SUBROUTINE use_sp_sub

   SUBROUTINE use_dp_sub(res)
      REAL(KIND=dp), INTENT(OUT) :: res
      res = 5._dp
   END SUBROUTINE use_dp_sub

END MODULE kk_M


PROGRAM kk
   USE kk_M
   IMPLICIT NONE
   REAL(KIND=sp) :: num_sp
   REAL(KIND=dp) :: num_dp

   num_sp = use_func(1._sp)
   WRITE(*,*) num_sp

   num_dp = use_func(1._dp)
   WRITE(*,*) num_dp

   CALL use_sub(num_sp)
   WRITE(*,*) num_sp

   CALL use_sub(num_dp)
   WRITE(*,*) num_dp

END PROGRAM kk

这篇关于基于返回类型的Fortran泛型函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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