Я пытаюсь определить процедуру interface
d как процедуру привязки по типу в определении Fortran type
, но, похоже, она не работает так, как можно было бы ожидать. Рассмотрим следующий модуль:сопряженные процедуры привязки типа в Fortran
module example_module
implicit none
private
interface add_them
module procedure add_them_integer,add_them_real
end interface add_them
type, public :: foo
integer, private :: a=1,b=2
real, private :: c=4.,d=5.
contains
procedure, public :: add => add_them
end type foo
contains
subroutine add_them_integer(self,x)
class(foo), intent(in) :: self
integer, intent(in) :: x
print *,self%a+self%b+x
end subroutine add_them_integer
subroutine add_them_real(self,x)
class(foo), intent(in) :: self
real, intent(in) :: x
print *,self%c+self%d+x
end subroutine add_them_real
end module example_module
и соответствующую программу, которая использует модуль:
program example
use example_module
implicit none
type(foo) :: foofoo
call foofoo%add(1)
call foofoo%add(2.)
end program example
Я бы ожидать, что это компилировать и результаты должны быть 4 и 11. Тем не менее, gfortran сообщает следующее сообщение об ошибке:
procedure, public :: add => add_them
1
Error: 'add_them' must be a module procedure or an external procedure with an explicit interface at (1)
обходной заключается в использовании generic
процедуры типа переплета вместо interface
г один, так что модуль следующим образом:
module example_module
implicit none
private
type, public :: foo
integer, private :: a=1,b=2
real, private :: c=4.,d=5.
contains
generic, public :: add => add_them_integer,add_them_real
procedure, private :: add_them_integer,add_them_real
end type foo
contains
subroutine add_them_integer(self,x)
class(foo), intent(in) :: self
integer, intent(in) :: x
print *,self%a+self%b+x
end subroutine add_them_integer
subroutine add_them_real(self,x)
class(foo), intent(in) :: self
real, intent(in) :: x
print *,self%c+self%d+x
end subroutine add_them_real
end module example_module
Это работает должным образом. Однако я не могу использовать процедуру generic
. Вышеприведенное является просто упрощенным примером для демонстрации проблемы, но в моем фактическом коде «add_them» не может быть процедура generic
, потому что «foo» на самом деле является производным типом, а «add_them» переопределяет процедуру, определенную в родительском типе; gfortran (по крайней мере) не разрешает generic
процедуры, переопределяющие базовые процедуры. Чтобы обойти это ограничение, я подумал, что вместо этого следует использовать interface
, но, как вы можете видеть в приведенном выше примере, хотя «add_them» определен правильно, компилятор жалуется, что «add_them» должен быть процедурой модуля или внешней процедурой с явный интерфейс ".
Любая помощь будет оценена по достоинству; заранее спасибо.
Строго говоря, то, что я пытался сделать, это обходить ограничение «вы не можете переопределять не общие процедуры с помощью общих» и пытались использовать сопряженную процедуру для этой цели. Я закончил работу, как сказал IanH, также делая родительскую процедуру общей. Для этого также необходимо добавить конструкцию 'select type' в родительскую процедуру (на самом деле это то, чего я хотел избежать), но она работает. – Pap
Я все еще не вижу, почему процедура сопряжения не может быть процедурой, связанной с типом, что делает процедуры «generic» единственным решением в приведенном выше примере. Fortran 2003/2008 даже позволяет переопределять имена типов с помощью сопряженной процедуры, в основном создавая «конструктор». Почему бы не использовать их как процедуры привязки типов? – Pap
То, что вы называете «сопряженной процедурой», является общим интерфейсом. Эквивалент для привязки является общей привязкой. Процедуры, которые реализуют привязки, имеют требования к ним вокруг переданных аргументов и т. Д. Если вы собираетесь использовать в автономном обобщенном синтаксисе интерфейса для указания общих привязок, тогда эти ограничения должны будут работать через этот синтаксис. Это было бы довольно грязно. – IanH