Pap*_*Pap 8 fortran interface type-bounds
我试图将一个interfaced过程定义为Fortran type定义中的类型绑定过程,但它似乎无法正常工作.考虑以下模块:
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
Run Code Online (Sandbox Code Playgroud)
以及使用该模块的相应程序:
program example
use example_module
implicit none
type(foo) :: foofoo
call foofoo%add(1)
call foofoo%add(2.)
end program example
Run Code Online (Sandbox Code Playgroud)
我希望这可以编译,结果应该是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)
Run Code Online (Sandbox Code Playgroud)
解决方法是使用generic类型绑定过程而不是interfaced one,以便模块如下:
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
Run Code Online (Sandbox Code Playgroud)
这按预期工作.但是,我不能使用generic程序.以上只是一个演示问题的简化示例,但在我的实际代码中,'add_them'不能是一个generic过程,因为'foo'实际上是一个派生类型,'add_them'覆盖了父类型中定义的过程; gfortran(至少)不允许generic程序覆盖基本程序.为了绕过这个限制,我认为我应该使用一个interface,但正如你在上面的例子中所看到的,尽管'add_them'被正确定义,但编译器抱怨"'add_them'必须是模块过程或带有显式的外部过程接口".
任何帮助,将不胜感激; 提前致谢.
您的第一部分代码的gfortran错误是正确的。进行通用绑定的方法是根据您代码的“按预期工作”部分。
如果父类型具有带有特定名称的特定绑定,则除了覆盖特定绑定之外,您无法在扩展名中重用该名称。
如果您希望add(注意名称add_them在第二种情况下没有出现)成为扩展名中的通用绑定,则使其成为父代中的通用绑定。