两个派生类型共享相同的子例程

时间:2015-07-16 13:40:53

标签: fortran derived-types

我在模块中有两个派生类型,IntervalInrset。两者都具有相同的功能,但是一个在实数上运行,另一个在整数上运行。

遇到的问题如下

lib/interval.f:85:11:

Procedure :: eptset => inrval_set
        1
Error: Argument 't' of 'inrval_set' with PASS(t) at (1) 
must be of the derived-type 'inrset'

lib/interval.f:55:11:

Procedure :: eptset => inrval_set
        1
Error: Argument 't' of 'inrval_set' with PASS(t) at (1) 
must be of the derived-type 'interval'

以下是Interval派生类型

Type Interval

Real (Real32) :: inf, sup

Contains
  Procedure :: eptset => inrval_set

End Type Interval

这是Intrset派生类型

Type Inrset

Integer (Int32) :: inf, sup

Contains
  Procedure :: eptset => inrval_set

End Type Inrset

这将是设置infsup的常用子例程。

Subroutine inrval_set  &
  (                    &
    t, inf, sup        &
  )

Class (*), Intent (InOut) :: t
Class (*), Intent (In) :: inf, sup

!!$--------------------------------------------------
!!$ Sets t% inf = inf;  t% sup = sup

Select Type (t)
Type Is (Interval)
  Call numtrf (t% inf, inf)
  Call numtrf (t% sup, sup)

Type Is (Inrset)
  Call numtrf (t% inf, inf)
  Call numtrf (t% sup, sup)

End Select 

End Subroutine inrval_set

1 个答案:

答案 0 :(得分:2)

无可否认,错误消息并不总是有用。在这种情况下,这是一个很好的提示。

派生类型Interval具有绑定名称为eptset的类型绑定过程,其接口与过程inrval_set的接口相同。这是你的难度。

我想你有一个像

这样的电话
type(Interval) range
call range%eptset(1._real32, 15._real32)

这是一个合理的目标。

但是,您依赖于传递对象伪参数,因此在inrval_set中,您的第一个伪参数t属于动态类型range。这是有缺陷的。

正如错误消息所示,Interval中的类型绑定过程的接口必须(因为它没有NOPASS属性)具有类型为Interval的伪参数。 class(*)的虚拟参数不是这样的。

您不希望使用NOPASS执行此方法。

你当然可以

call inrval_set(range, 1._real32, 15._real32)

作为一种选择。但是有类型约束的方式吗?

你可以考虑templating。或者,有一个(抽象)父类。或者使用适当的接口提供类型绑定过程 - 每种类型一个。

基本上,您在select type块中重复代码,因此您也可以使用通用/动态分辨率重复代码。

相关问题