微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用可选参数重载函数

如何解决使用可选参数重载函数

我想编写一个接受 optional 参数的过程,参数可能是 FooType 类型或 BarType 类型,这样该程序是有效的:

module m
  implicit none
  
  type :: FooType
  end type
  
  type :: BarType
  end type
end module

program mwe
  use m
  implicit none
  
  type(FooType),allocatable :: foo(:)
  type(BarType),allocatable :: bar(:)
  
  call func()
  call func([FooType()])
  call func([BarType()])
  call func(foo)
  call func(bar)
end program

我目前的尝试是:

module m
  implicit none
  
  type :: FooType
  end type
  
  type :: BarType
  end type
  
  interface func
    module procedure func_FooType
    module procedure func_BarType
  end interface
contains

subroutine func_FooType(input)
  type(FooType),intent(in),optional :: input(:)
  write(*,*) 'foo'
end subroutine

subroutine func_BarType(input)
  type(BarType),intent(in) :: input(:)
  write(*,*) 'bar'
end subroutine
end module

但这行不通。使用 gfortran 10.1.0ifort 2021.1 编译给出输出

foo
foo
bar
foo
bar

问题是最后一次调用 func(bar)bar 不是 allocated,因此如果将其传递给 optional 参数,则它不会是 present。然而,被调用的过程是 func_BarType,它认为它的 input 不是 optional,因此无法检查 input 是否是 present。实际上,如果我将 input 更改为标量而不是数组,则在 gfortran 下对 func(bar)调用会在运行时崩溃。

解决方法

我认为唯一的方法是使用一个带有可选多态参数的函数,所以:

subroutine func(input)
  class(*),intent(in),optional :: input(:)
  
  if (present(input)) then
    select type(input); type is(FooType)
      ! Code for FooType.
    type is(BarType)
      ! Code for BarType.
    class default
      ! Any other class. Probably throw an error.
    end select
  else
    ! Code for input not present.
  endif
end subroutine

我很惊讶似乎没有办法在不使用多态类型的情况下做到这一点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。