共享相同子例程的两个派生类型
Two derived types sharing same subroutine
我在一个模块中有两个派生类型,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
诚然,错误信息并不总是有用的。在这种情况下,这是一个很好的提示。
您的派生类型 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 分辨率重复代码。
我在一个模块中有两个派生类型,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
诚然,错误信息并不总是有用的。在这种情况下,这是一个很好的提示。
您的派生类型 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 分辨率重复代码。