【问题标题】:interfaced type-bound procedures in FortranFortran 中的接口类型绑定过程
【发布时间】:2013-12-07 01:34:21
【问题描述】:

我正在尝试将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

以及使用该模块的相应程序:

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 类型绑定过程而不是interfaced 一个,因此模块如下:

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'必须是模块过程或外部过程具有显式接口”。

任何帮助将不胜感激;提前致谢。

【问题讨论】:

    标签: interface fortran type-bounds


    【解决方案1】:

    第一段代码的 gfortran 错误是正确的。进行通用绑定的方法是按照您的“按预期工作”部分的代码。

    如果父类型具有特定名称的特定绑定,则您不能在扩展中重用该名称,只能覆盖特定绑定。

    如果您希望 add(注意名称 add_them 没有出现在您的第二种情况中)成为扩展中的通用绑定,则使其成为父级中的通用绑定。

    【讨论】:

    • 严格来说,我试图做的是绕过“你不能用通用程序覆盖非通用程序”的限制,并尝试为此目的使用接口程序。我最终像 IanH 所说的那样,使父程序也通用。这也需要向父过程添加一个select type 构造(这实际上是我想要避免的)但它可以工作。
    • 但是,我仍然不明白为什么接口过程不能是类型绑定过程,这使得generic 过程成为上面示例中的唯一解决方案。 Fortran 2003/2008 甚至允许通过接口过程覆盖类型名称,本质上是创建一个“构造函数”。为什么不将它们也用作类型绑定过程?
    • 所谓的“接口过程”是一个通用接口。绑定的等价物是泛型绑定。实现绑定的过程对传递的参数等有要求。如果您打算使用独立的泛型接口语法来指定泛型绑定,那么这些限制必须通过该语法起作用。那会很混乱。
    • 我怀疑generic type-bounds 是唯一的出路,所以发布这个只是为了确定。我不能抱怨,真的。毕竟,正是这些限制使 Fortran 成为高性能计算的理想选择,并迫使程序员编写结构化代码以避免潜在的陷阱。
    猜你喜欢
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多