Как избежать перезаписи одного и того же интерфейса для процедуры с отложенным типом, реализованной в подмодуле?

#fortran

Вопрос:

Рассмотрим следующий код, который определяет abstract тип foo с deferred процедурой sub , и тип foo2 , который расширяет foo :

 MODULE m
  TYPE, ABSTRACT:: foo
  CONTAINS
    PROCEDURE(sub_int), DEFERRED:: sub
  END TYPE

  INTERFACE
    SUBROUTINE sub_int(THIS, x)
      IMPORT:: foo
      CLASS(foo), INTENT(IN):: THIS
      DOUBLE PRECISION, INTENT(INOUT):: x
    END SUBROUTINE
  END INTERFACE

  TYPE, EXTENDS(foo):: foo2
  CONTAINS
    PROCEDURE:: sub
  END TYPE

  INTERFACE
    MODULE SUBROUTINE sub(THIS, x)
      CLASS(foo2), INTENT(IN):: THIS
      DOUBLE PRECISION, INTENT(INOUT):: x
    END SUBROUTINE
  END INTERFACE
END MODULE

SUBMODULE (m) s
CONTAINS
  MODULE PROCEDURE sub
    x= x**2
  END PROCEDURE
END SUBMODULE
 

Есть ли способ избежать написания второго interface ?

Я понимаю , что это необходимо для того, чтобы объявить sub как module procedure (в противном случае реализацию нужно было бы выполнять в module , а не в submodule ), но это единственный способ сделать это?

Другими словами, можно ли реализовать процедуру sub foo2 без переписывания всего интерфейса для нее?

Комментарии:

1. Это не просто переписано. Как только вы это сделаете class(foo) , и позже class(foo2) . Как только блок интерфейса становится абстрактным, а позже-нет.

2. Блока интерфейса в МОДУЛЕ ABSTRACT а в моем примере нет. Кроме того, я не уверен, CLASS(foo2) действительно ли что-то добавляет к CLASS(foo) …любому типу , который будет расширяться foo CLASS(foo) , поэтому для переопределения процедур в расширенных типах потребуется foo аргумент типа. Пожалуйста, поправьте меня, если я ошибаюсь. В любом случае, знаете ли вы, является ли это единственным способом достичь того, что я описываю в своем примере?

3. Извините, ваш sub_int интерфейсный блок действительно не является абстрактным, но, возможно, так и должно быть на самом деле. Но все же есть разница между просто subroutine и module subroutine . Вы не просто копируете один и тот же материал.

4. На самом деле я специально не использовал абстрактный интерфейс, чтобы показать, что, на мой взгляд, по крайней мере часть информации (аргументы процедуры) повторяется, и код это допускает. Я использую абстрактные интерфейсы в своем реальном коде для отложенных процедур с привязкой к типу, и я согласен, что их следует использовать для этой цели. Тем не менее, я просто хотел бы знать, является ли это единственным способом сделать это, или есть другие способы, которые могут заставить меня «сэкономить» некоторые строки кода.

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

Ответ №1:

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

Будет ли процедура назначена одной (или несколькими!) привязками одного (или нескольких!) типов, совершенно не имеет значения.

Комментарии:

1. Спасибо вам за ваш ответ! В комментарии к вопросу @veryreverie есть ссылка на обсуждение этой проблемы, и предлагается решение с использованием макросов препроцессора. Макрос используется, чтобы избежать перезаписи всего интерфейса; вместо этого записывается макрос. Мне это кажется очень полезным, но рекомендуется ли использовать макросы препроцессора для этой цели, или это считается (более или менее) плохой практикой? Если это плохая практика, то почему это так?

2. Это кажется мне несвязанным вопросом. Я не использую макросы. Я считаю их плохой практикой в коде «Фортран». Во — первых, как только вы их используете, ваш код больше не является Fortran, как определено в стандарте ISO/IEC 1539-1.