Стандарт запрещает использование нескольких фиктивных аргументов переданного объекта, а также фиктивных аргументов переданного объекта, которые являются массивами или указателями. Стандарт не запрещает фиктивные аргументы переданного объекта, которые являются классами, содержащими массивы или указатели.
Это может быть реализовано как
module m_Parent
type, abstract :: Parent
end type
type, abstract :: ParentPair
contains
procedure(f_ParentPair), deferred :: f
end type
abstract interface
subroutine f_ParentPair(foobar)
import ParentPair
implicit none
class(ParentPair), intent(in) :: foobar
end subroutine
end interface
end module
module m_Child
use m_Parent
type, extends(Parent) :: Child
contains
procedure, public :: f => f_Child
end type
type, extends(ParentPair) :: ChildPair
type(Child) :: foo
type(Child) :: bar
contains
procedure, public :: f => f_ChildPair
end type
contains
subroutine f_ChildPair(foobar)
implicit none
class(ChildPair), intent(in) :: foobar
call foobar%foo%f(foobar%bar)
end subroutine
subroutine f_Child(foo,bar)
implicit none
class(Child), intent(in) :: foo
class(Child), intent(in) :: bar
end subroutine
end module
Это не самое элегантное решение, и оно требует создание и поддержка целого класса ChildPair
для каждой реализации Child
.
Согласно operf, в ifort 19.1 это имеет незначительные издержки по сравнению с оператором select type
.