【问题标题】:Overloading functions with optional arguments使用可选参数重载函数
【发布时间】:2021-05-14 11:50:14
【问题描述】:

我想编写一个带有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) 的调用会在运行时崩溃。

【问题讨论】:

  • 分配到零大小是可接受的替代方案吗?
  • 我不这么认为。我当前的用例是字符串解析,例如一个空字符串可能代表一个空行,而没有参数则意味着根本没有行。另外,我也有参数不是数组的情况。
  • 可能有一个值表示“忽略此参数”,但这似乎是一个令人不快的解决方案。
  • “问题是最终调用,对 func(bar)。bar 没有分配,所以输入不存在”。这不是真的。 inputfunc_BarType 中不是可选的,因此它存在。未分配的实际参数bar 使其成为非法子例程调用。
  • @IanBush,当 dummy 是可选的不可分配时,实际不能分配。

标签: fortran overload-resolution optional-arguments


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2013-05-23
    • 2010-10-16
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多