Могу ли я имитировать c несколько фиктивных аргументов переданного объекта без добавления зависимостей? - PullRequest
0 голосов
/ 13 февраля 2020

Я ранее спрашивал Могу ли я имитировать c несколько фиктивных аргументов переданного объекта в Фортране?

Я слишком упростил задачу для этого вопроса и стал лучшим примером кода Я хотел бы написать это

module m_Parent
  type, abstract :: Parent
  contains
    procedure(f_Parent), deferred :: f
  end type

  abstract interface
    subroutine f_Parent(foo,bar)
      import Parent
      implicit none
      class(Parent), intent(in) :: foo
      class(Parent), intent(in) :: bar
    end subroutine
  end interface
end module

module m_Child
  use m_Parent

  type, extends(Parent) :: Child
  contains
    procedure, public :: f => f_Child
  end type
contains
  subroutine f_Child(foo,bar)
    implicit none
    class(Child), intent(in) :: foo
    class(Child), intent(in) :: bar
  end subroutine
end module

с ограничением, что m_Parent может не иметь зависимостей от m_Child, чтобы избежать циклических зависимостей и разрешить множество классов Child без необходимости обновления m_Parent с подробным описанием каждого.

Как и прежде:

  • код, представленный здесь, запрещен стандартом Фортрана.
  • конструкция select type слишком медленная .

Могу ли я имитировать c поведение, которое приведёт вышеупомянутый код, если несколько стандартных фиктивных аргументов переданного объекта будут разрешены стандартом Фортрана?

1 Ответ

0 голосов
/ 14 февраля 2020

Стандарт запрещает использование нескольких фиктивных аргументов переданного объекта, а также фиктивных аргументов переданного объекта, которые являются массивами или указателями. Стандарт не запрещает фиктивные аргументы переданного объекта, которые являются классами, содержащими массивы или указатели.

Это может быть реализовано как

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...