我想要一个派生类型a
,它是空的。从这个派生类型我想定义扩展a的其他类型。假设所有这些类型扩展都包含一些generic
过程名称value
,即value => valuea1
,value => valuea2
等。
如果我想将类a的变量传递给其他过程,我需要用class(a)
声明该过程的相关伪参数。但是,如果我这样做,那么引用伪参数的value
会导致编译失败,因为类a实际上是空的 - 只有类型扩展包含该过程。
我可以通过在a的类型定义中使用一些名为value
的过程(然后覆盖扩展名)来解决这个问题。但是,鉴于我从不想声明任何类型为a的对象,这看起来很混乱。有可能解决这个问题吗?
答案 0 :(得分:3)
是的,您甚至可以为abstract
类型声明类型绑定过程。它可以是真正的类型绑定过程,也可以只是abstract interface
。
type, abstract :: a
contains
procedure :: valuea1, valuea2
generic value :: value => valuea1, valuea2
end type
abstract interface
! the headers of valuea1, valuea2 here
! they should have a passed dummy argument class(a)
! and some other argument for the generic resolution
! for example:
subroutine valua1(self, x)
class(a), intent(in) :: self
real, intent(inout) :: x
end subroutine
subroutine valua2(self, x)
class(a), intent(in) :: self
integer, intent(inout) :: x
end subroutine
end interface
这样您就无法创建type(a)
的变量,但您可以制作实现其value
版本的扩展类型。
答案 1 :(得分:2)
与@VladimirF的回答类似,但是要澄清
我实际上并不需要通用的解决方案; valuea1和valuea2接受我想到的问题的相同类型的参数,我只想在一个类型扩展中绑定到valuea1而在另一个类型扩展中绑定valuea2。
然后,这里,base(abstract)类型定义了一个延迟的类型绑定过程value()
,其接口以class(a)
作为传递的参数。可以添加其他参数。每个扩展类型使用自己的过程定义/覆盖此类型绑定过程。
这意味着,在我们的最终子例程调用test_sub
中,class(a)
伪参数确实具有%value()
。
module types
! The base type
type, abstract :: a
contains
procedure(value_if), deferred :: value
end type a
! The interface for the type-bound procedures
abstract interface
subroutine value_if(var)
import a
class(a) var
end subroutine value_if
end interface
! The extending types, overriding the value subroutine
type, extends(a) :: a1
contains
procedure :: value => value_a1
end type a1
type, extends(a) :: a2
contains
procedure :: value => value_a2
end type a2
contains
subroutine value_a1(var)
class(a1) var
print*, "Value of a1"
end subroutine value_a1
subroutine value_a2(var)
class(a2) var
print*, "Value of a2"
end subroutine value_a2
end module types
program test
use types
type(a1) x
type(a2) y
call x%value
call y%value
call test_sub(x)
call test_sub(y)
contains
subroutine test_sub(var)
class(a) var
call var%value ! This is defined
end subroutine test_sub
end program test
这会产生输出
a1的价值 a2的价值 a1的价值 a2的值