使用可选参数重载函数
Overloading functions with optional arguments
我想编写一个带有 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.0
或 ifort 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
令我惊讶的是,似乎没有不使用多态类型就可以做到这一点的方法。
我想编写一个带有 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.0
或 ifort 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
令我惊讶的是,似乎没有不使用多态类型就可以做到这一点的方法。