Как создать процедуру, которая может иметь разные входные аргументы для каждого типа, расширяющего исходный тип - PullRequest
2 голосов
/ 07 мая 2019

У меня есть производный тип:

module type_1_mod
  implicit none

  public :: type1

  type :: type1
    private
    integer :: a, b
  contains
    procedure, public :: mandatoryProcedureForAllExtends
  end type type1

contains

  subroutine mandatoryProcedureForAllExtends(this, varInt, varReal, varLogic)
    class(type1) :: this
    integer :: varInt
    real :: varReal
    logical :: varLogic

    *** something ***
  end subroutine mandatoryProcedureForAllExtends

end module type_1_mod

Я хочу объявить другие производные типы, которые расширят этот, который я написал выше, и у всех них будет процедура mandatoryProcedureForAllExtends, но я хочу этопроцедура не имеет обязательной структуры - это означает, что пользователь может переопределить процедуру другой процедурой с другими входными аргументами, например:

module type_2_mod
  use type_1_mod
  implicit none

  public :: type2

  type, extends(type1) :: type2
    private
  contains
    procedure, public :: mandatoryProcedureForAllExtends
  end type type2

contains

  subroutine mandatoryProcedureForAllExtends(this, varReal, varReal2, varReal3, varReal4, varLogic)
    class(type2) :: this
    real :: varReal, varReal2, varReal3, varReal4,
    logical :: varLogic

    *** something ***
  end subroutine mandatoryProcedureForAllExtends

end module type_2_mod

Таким образом, у типа, расширяющего тип1, есть процедура с тем же именем, но переопределеннаячтобы иметь другое число и тип переменных.

Я пытался написать type1 как реферат и использовать отложенную процедуру, но для этого требуется явно объявить интерфейс со структурой процедуры.Я также пытался использовать что-то вроде

при объявлении типа 1

  contains
    procedure, public :: type1VersionOfMandatory
    generic :: mandatoryProcedureForAllExtends => type1VersionOfMandatory

contains

  subroutine type1VersionOfMandatory(this, varInt, varReal, varLogic)
    class(type1) :: this
    integer :: varInt
    real :: varReal
    logical :: varLogic

    *** something ***
  end subroutine type1VersionOfMandatory

при объявлении типа 2

  contains
    procedure, public :: type2VersionOfMandatory
    generic :: mandatoryProcedureForAllExtends => type2VersionOfMandatory

contains

  subroutine type2VersionOfMandatory(this, varReal, varReal2, varReal3, varReal4, varLogic)
    class(type2) :: this
    real :: varReal, varReal2, varReal3, varReal4,
    logical :: varLogic

    *** something ***
  end subroutine type2VersionOfMandatory

Но я получаю сообщение об ошибке при попытке компиляции: Error: Undefined specific binding ‘type1VersionOfMandatory’ as target of GENERIC ‘mandatoryProcedureForAllExtends’ at (1) и Error: Undefined specific binding ‘type2VersionOfMandatory’ as target of GENERIC ‘mandatoryProcedureForAllExtends’ at (1)

Я также попытался просто переопределить процедуру, определив ее с тем же именем снова, но я получил некоторые ошибки, такие как Error: Dummy argument ‘varInt’ of ‘mandatoryProcedureForAllExtends’ at (1) should be named ‘varReal’ as to match the corresponding argument of the overridden procedure

Так что на данный момент я даже не уверен, возможно ли это сделать с помощью Fortran.Я предпочитаю, чтобы type1 не был абстрактным типом, но если это требуется, все может быть так.

...