依赖于参数的Fortran函数返回类型

3
如果您查看内在函数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

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

必须是一个函数吗?将可选参数(每种类型)传递给子程序是否可行? - Ross
@Ross,目前我没有特定的应用程序需要这个。 - chw21
2个回答

3

不。根据F2015草案,标准语言中不可能实现此功能。在这方面,内置过程是特殊的。

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

必须使用常量表达式给出类型参数,而变量不是常量。在范围中指定对象类型的规则实际上更加严格。


1
或者...将您的函数打包到一个模块中,拥有所有 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

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

1
现在我知道我可以使用过程重载来使相同的名称与不同的过程相关联,具体取决于参数的类型。但我想知道返回值的类型是否可以取决于参数的值。 - Vladimir F Героям слава
我的意思是,如果你想展示你的例子,可以保留它,但至少试着回答被问到的问题。 - Vladimir F Героям слава

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接