Fortran函数,返回类型取决于参数

时间:2016-10-11 05:09:16

标签: fortran

如果查看内部函数CEILING的定义,它有一个可选参数KIND,可用于强制返回值的整数类型。

有没有办法在Fortran中实现我自己的函数,以便获得类型,甚至更好的函数返回值的类型取决于参数?我尝试过这样的事情:

program test_kind
    use iso_fortran_env
    implicit none
    integer(kind=int32) :: a
    print*, kind(a)
    print*, kind(kt(int16))
    print*, kind(kt(int32))
contains
    function kt(kind)
        implicit none
        integer, intent(in) :: kind
        integer(kind=kind) :: kt
        kt = 100
    end function kt
end program test_kind

但它失败并出现错误:

test_kind.f90:12:21:

         integer(kind=kind) :: kt
                     1
Error: Parameter ‘kind’ at (1) has not been declared or is a variable, 
which does not reduce to a constant expression

现在我知道我可以使用过程重载来根据参数的类型将相同的名称与不同的过程相关联。但我问的是,返回值的类型是否可以取决于参数的

2 个答案:

答案 0 :(得分:2)

没有。从F2015草案开始,标准语言是不可能的。在这方面,内在程序是特别的。

作为数据对象的虚拟参数始终是非内部过程中的变量。

种类参数必须由常量表达式给出,变量不是常量。在范围内提名对象类型的规则实际上更具限制性。

答案 1 :(得分:0)

或者......将您的功能打包成一个模块并拥有KT的所有风格。

MODULE KTM
use iso_fortran_env
implicit none
PRIVATE
INTERFACE Kinder
  MODULE PROCEDURE kt_byte, kt_int !kt_long, kt_long_long
END INTERFACE Kinder
PUBLIC Kinder
contains
  function kt_byte(kind_In)
      implicit none
      integer(KIND=int8_t), intent(in) :: kind_In
      integer(kind=int8_t)             :: kt_byte
      kt_byte = 100
  end function kt_byte

  function kt_Int(kind_In)
      implicit none
      integer(KIND=int16_t), intent(in) :: kind_In
      integer(kind=int16_t)             :: kt_Int
      kt_Int = 200
  end function kt_Int

  function kt_long(kind_In)
      implicit none
      integer(KIND=int32_t), intent(in) :: kind_In
      integer(kind=int32_t)             :: kt_long
      kt_long = 400
  end function kt_long

  function kt_8B(kind_In)
      implicit none
      integer(KIND=c_long), intent(in) :: kind_In
      integer(kind=c_long)             :: kt_8B
      kt_8B = 800
  end function kt_8B
end MODULE KTM

然后使用您需要各种KT功能的模块......

program test_kind
use iso_fortran_env
USE KTM  !make sure it is in the -I<path> and/or some -L<path> -l<lib>
implicit none
integer(kind=int32)   :: a
integer(kind=int16_t) :: b
integer(kind=int8_t)  :: c
integer(kind=int64)   :: d
integer(kind=c_long)  :: e
REAL :: f
print*, kinder(a)
print*, kinder(b)
print*, kinder(c)
print*, kinder(d)
print*, kinder(e)
!The following line will give a compile error
!print*, Kinder(f)
end program test_kind

或者,如果它没有在常用的库中使用,那么将模块放在程序之前,然后使用程序跟随...在单个文件中。