Объявление класса Фортран фиктивного аргумента

Я хотел бы иметь производный тип, a, который пуст. Из этого производного типа я хотел бы определить другие типы, которые расширяют. Предположим, что все эти расширения типа содержат некоторые generic название процедуры, valueт.е. value => valuea1, value => valuea2, так далее.

Если я затем хочу передать переменные класса a какой-либо другой процедуре, мне нужно объявить соответствующий фиктивный аргумент этой процедуры с помощью class(a), Если я сделаю это, однако, то ссылка на value аргумента-пустышки приводит к сбою компиляции, потому что класс a фактически пуст - только процедуры расширения содержат процедуру.

Я мог предположительно обойти это, имея некоторую процедуру под названием value внутри определения типа a (затем переопределяя в расширениях). Однако, учитывая, что я никогда не хочу объявлять какой-либо объект с типом a, это кажется грязным. Можно ли обойти это?

2 ответа

Да, вы можете объявить процедуру, связанную с типом, даже для abstract тип. Это может быть процедура, связанная с реальным типом, или просто abstract interface,

type, abstract :: a
contains
  procedure :: valuea1, valuea2
  generic value :: value => valuea1, valuea2
end type


abstract interface
  ! the headers of valuea1, valuea2 here
  ! they should have a passed dummy argument class(a)
  ! and some other argument for the generic resolution
  ! for example:

  subroutine valua1(self, x)
    class(a), intent(in) :: self
    real, intent(inout) :: x
  end subroutine

  subroutine valua2(self, x)
    class(a), intent(in) :: self
    integer, intent(inout) :: x
  end subroutine

end interface

Таким образом, вы не можете создавать переменные type(a), но вы можете создавать расширенные типы, которые реализуют свои собственные версии value,

Похоже на ответ @VladimirF, но, принимая во внимание, что

Мне на самом деле не нужно общее разрешение; valuea1 и valuea2 принимают тот же тип аргументов для проблемы, которую я имею в виду, я просто хочу связать valuea1 в одном расширении типа и valuea2 в другом расширении типа.

Здесь, тогда, базовый (абстрактный) тип определяет отложенную процедуру с привязкой к типу value() с интерфейсом, принимающим class(a) как переданный аргумент. Другие аргументы могут быть добавлены. Каждый расширяющий тип определяет / переопределяет эту связанную с типом процедуру своей собственной процедурой.

Это значит, чем в нашем последнем вызове подпрограммы test_sub class(a) фиктивный аргумент имеет %value(),

module types

! The base type
  type, abstract :: a
   contains
     procedure(value_if), deferred :: value
  end type a

! The interface for the type-bound procedures
  abstract interface
     subroutine value_if(var)
       import a
       class(a) var
     end subroutine value_if
  end interface

! The extending types, overriding the value subroutine

  type, extends(a) :: a1
   contains
     procedure :: value => value_a1
  end type a1

  type, extends(a) :: a2
   contains
     procedure :: value => value_a2
  end type a2

contains

  subroutine value_a1(var)
    class(a1) var
    print*, "Value of a1"
  end subroutine value_a1

  subroutine value_a2(var)
    class(a2) var
    print*, "Value of a2"
  end subroutine value_a2

end module types


program test

  use types

  type(a1) x
  type(a2) y

  call x%value
  call y%value

  call test_sub(x)
  call test_sub(y)

contains

  subroutine test_sub(var)
    class(a) var
    call var%value  ! This is defined
  end subroutine test_sub

end program test

Это производит вывод

Значение а1
Значение а2
Значение а1
Значение а2

Другие вопросы по тегам