#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.