我在模块中有两个派生类型,Interval
和Inrset
。两者都具有相同的功能,但是一个在实数上运行,另一个在整数上运行。
遇到的问题如下
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
这将是设置inf
和sup
的常用子例程。
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
答案 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
块中重复代码,因此您也可以使用通用/动态分辨率重复代码。