2

为什么覆盖过程中的参数名称需要与抽象接口的名称相匹配?

我明白,这些参数的 , 等清楚地TYPE需要INTENT匹配接口,但是为什么编译器要关心我所说的变量呢?

在下文中,我定义了一个简单的抽象实用程序类,其中包含一个EVAL采用双精度参数的延迟过程。

!------------------------------------- an abstract utility class !
type, abstract :: func_1d
contains
    procedure(interface_1d),deferred :: eval
end type func_1d

!-------------------------------------------- interface for eval !
abstract interface
function interface_1d(this,data) result(rval)
    import :: func_1d
    class(func_1d), intent(inout) :: this
    real*8        , intent(in)    :: data
    real*8 :: rval
end function interface_1d
end interface

定义一个覆盖类和一个实现EVAL

type, extends(func_1d) :: foo
contains
    procedure, pass :: eval => eval_foo
end type foo

function eval_foo(this,another_variable_name) result(rval)
    implicit none
    class(foo), intent(inout) :: this
    real*8, intent(in) :: another_variable_name
    real*8 :: rval

    !! etc

end function eval_foo

我收到以下错误gfortran

错误:(1)处“eval”的虚拟参数“another_variable_name”应命名为“data”,以匹配被覆盖过程的相应参数

如果我改为替换所有内容DATAANOTHER_VARIABLE_NAME则可以按预期编译和运行。

但这对我来说似乎很愚蠢。我希望能够FUNC_1D多次继承,并且在各种情况下并且DATA每次都被迫调用我的变量似乎很荒谬。

我不明白为什么编译器应该对参数感兴趣而不是TYPEINTENT

4

1 回答 1

4

详细阐述高性能标记的评论

我不知道,但我怀疑这可能取决于 Fortran 的参数关键字功能,这意味着您可以像这样调用您的函数fun_1d(data=the_data,this=that),即您可以在调用中命名参数而不是依赖位置匹配。

考虑以下

type, extends(func_1d) :: foo
 contains
  procedure, pass :: eval => eval_foo
end type foo

type, extends(func_1d) :: bar
 contains
  procedure, pass :: eval => eval_bar
end type bar

带有适当的过程定义和接口

real*8 function eval_foo(this,foo_var)
  class(foo), intent(inout) :: this
  real*8, intent(in) :: foo_var
end function

real*8 function eval_bar(this,bar_var)
  class(bar), intent(inout) :: this
  real*8, intent(in) :: bar_var
end function

然后稍后

class(func_1d), allocatable :: baz
allocate (foo_or_bar :: baz)  ! For one of the types foo, bar

如果有的话,哪个对参数关键字有意义?

print*, baz%eval(data=s)
print*, baz%eval(foo_var=s)
print*, baz%eval(bar_var=s)

[在某些情况下,这会更加明显,尤其是在使用可选的虚拟参数时。]


该标准要求您保留相同的虚拟参数名称(很可能避免上述问题)。参见 12.4.1 ISO/IEC 1539-1:2010:

12.4.1 接口和抽象接口

过程的接口决定了可以调用它的引用形式。该过程的接口由它的名称、绑定标签、通用标识符、特征和它的虚拟参数的名称组成。过程的特征和绑定标签是固定的,但接口的其余部分可能在不同的上下文中有所不同,除了对于单独的模块过程主体(12.6.2.5),虚拟参数名称和是否递归应相同如在其相应的单独接口主体(12.4.3.2)中。

这表明使用相同接口的单独过程应具有与接口相同的伪参数名称。4.5.7.3 进一步加强了这一点:

覆盖和覆盖的类型绑定过程应满足以下条件。
- [...]
- 按位置对应的虚拟参数应具有相同的名称和特征,但传递对象虚拟参数的类型除外。

于 2015-03-12T14:37:45.390 回答