I am trying to define an interface
d procedure as a type-bound procedure in a Fortran type
definition, but it seems it doesn't work as one would expect. Consider the following module:
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
and the corresponding program that uses the module:
program example
use example_module
implicit none
type(foo) :: foofoo
call foofoo%add(1)
call foofoo%add(2.)
end program example
I would expect this to compile and results should be 4 and 11. However, gfortran reports the following error:
procedure, public :: add => add_them
1
Error: 'add_them' must be a module procedure or an external procedure with an explicit interface at (1)
A workaround is to use generic
type-bound procedure instead of an interface
d one, so that the module is as follows:
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
This works as expected. However, I cannot use a generic
procedure. The above is just a simplified example to demonstrate the problem, but in my actual code 'add_them' cannot be a generic
procedure because 'foo' is actually a derived-type and 'add_them' overrides a procedure defined in the parent type; gfortran (at least) does not allow generic
procedures overriding base procedures. To bypass this restriction, I thought I should use an interface
instead, but as you can see in the above example, although 'add_them' is defined correctly, compiler complains that "'add_them' must be a module procedure or an external procedure with an explicit interface".
Any help would be appreciated; thanks in advance.
The gfortran error for your first section of code is correct. The way to do generic bindings is as per your "works as expected" section of code.
If a parent type has a specific binding with a certain name, then you cannot reuse that name in extensions, other than to override the specific binding.
If you want
add
(note the nameadd_them
doesn't appear in your second case) to be a generic binding in extensions, then make it a generic binding in the parent.