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

Two derived types sharing same subroutine

我在一个模块中有两个派生类型,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

诚然,错误信息并不总是有用的。在这种情况下,这是一个很好的提示。

您的派生类型 Interval 有一个绑定名称 eptset 和与过程 inrval_set 相同接口的类型绑定过程。这就是你的难处。

我想你会想到这样的电话

type(Interval) range
call range%eptset(1._real32, 15._real32)

这是一个合理的目标。

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

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

您不想使用 NOPASS 来执行此方法。

当然可以

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

作为一种选择。但是有类型绑定的方法吗?

是的。

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

本质上,您是在 select type 块中重复代码,因此您也可以使用 generic/dynamic 分辨率重复代码。