A Fortran function/subroutine that could return either a real, an integer or a string.

人盡茶涼 提交于 2019-12-20 04:32:56

问题


I would like to know how to create a function that either returns a real, an integer or a string.

For example, the call would be write(*,*)dt%get() where get() would return :

  • an integer if dt%isInteger = .true.
  • a real if dt%isReal = .true.
  • a character if dt%isStr = .true.

I believe this might be possible by using an abstract interface to make procedure get() point to either procedure getInteger(), getReal() or getStr() but the abstract interface definition needs to define the ouput type which is, in my case, variable.

Here is the related code:

type :: dt
    real(dp) :: realValue
    integer :: integerValue
    character(*) :: strValue
    logical :: isReal, isInteger, isStr
    procedure(intf), pointer :: get
contains
    procedure :: getReal, getInteger, getStr
end type

abstract interface
    function intf(self)
        import dt
        class(dt) :: self
        ??? :: intf
    end function
end interface

Any idea ?


回答1:


That is simply impossible in Fortran.

You can use a generic interface with different specific functions, but these functions must have arguments of different types (see how several intrinsic functions, like transfer() use a mold argument). This is called the TKR (type, kind, rank) resolution. Generic functions cannot be distinguished based on a value of an argument.

type :: dt
    real(dp) :: realValue
    integer :: integerValue
    character(*) :: strValue             !!!! <= THIS IS WRONG !!!!
    logical :: isReal, isInteger, isStr
contains
    generic :: get => getReal, getInteger, getStr
    procedure :: getReal, getInteger, getStr
end type

function getReal(self, mold)
  class(dt) :: self
  real, intent(in) :: mold
end function

function getInteger(self, mold)
  class(dt) :: self
  integer, intent(in) :: mold
end function

function getString(self, mold)
  class(dt) :: self
  character(*), intent(in) :: mold
end function

As you see, you have to know the correct type when calling get(). You call it like

real_variable = object%get(1.0)
integer_variable = object%get(1)

Be also careful about strings of different lengths. I marked it above. You probably want character(:), allocatable.


You can make also function which returns a generic container and then extract the value from the container. The extraction could even be done directly using an overloaded assignment for the container.

You could also just return an unlimited polymorphic variable (class(*)).



来源:https://stackoverflow.com/questions/48326191/a-fortran-function-subroutine-that-could-return-either-a-real-an-integer-or-a-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!