las*_*vec 3 generics fortran interface abstract fortran90
我在 Fortran90 中编码,即使我知道应该避免它,我也需要使用抽象类型。现在我希望定义一个函数,它可以在参数中采用抽象类型或派生类型。为此,我想创建两个函数的接口,但出现以下错误:
(1) 通用接口“初始化”中的模糊接口“初始化抽象”和“初始化逻辑”
代码如下所示:
type type1
contains
procedure, pass(transf) :: initialize_logic
procedure, pass(transf) :: initialize_abstract
end type
interface initialize
module procedure initialize_logic
module procedure initialize_abstract
end interface
function initialize_logic(element, element_logic)
type(type1), pointer :: element
type(type_logic), pointer :: element_logic
end function
function initialize_abstract(element, element_abstract)
type(type1), pointer :: element
class(type_abstract), pointer :: element_abstract
end function
Run Code Online (Sandbox Code Playgroud)
type_abstract 是从 type_logic 扩展而来的。
我不知道如何摆脱这个消息错误,我真的需要能够使用抽象类型或扩展类型(此处:“logic_type”)来调用它,例如:
class(type_abstract), pointer :: element_abstract
type(type_logic), pointer :: element_logic
type(type1) :: e1, e2
call e1%initialize(element_abstract)
call e2%initialize(element_logic)
Run Code Online (Sandbox Code Playgroud)
如果我只有一个初始化程序,将抽象类作为参数,在使用扩展类型进行初始化时,我会收到以下错误:
错误:(1) 处“element_abstract”的实际参数必须具有相同的声明类型
有任何想法吗 ?先感谢您
编辑:完全重新设计,添加了抽象类方法。
有两种方法可以做到。一种使用select type构造来确定动态类型element在运行时调用正确的初始化过程。
另一种方法使用一个抽象类来声明一个延迟过程initialize_t1,该过程将由每个子类以不同的方式实现。请注意两件事,首先我调用了一个派生类型abstract以保持您的命名约定,但是它相当混乱并且不是一个好习惯。然后调用真正抽象的类veryAbstract来暗示其用途,并且仍然保持您的命名约定。另一点要注意的是,initialize_from_...过程绑定到veryAbstract子类而不是type1类。这可能令人困惑,但这是实现您所追求的目标的诀窍。
两种方式都用 ifort 14 进行了测试。
方法一(选择类型):
module test2
type abstract
integer :: x
contains
end type abstract
type, extends(abstract) :: logic
integer :: y
contains
end type logic
type type1
integer :: x
contains
procedure :: initialize => initialize_type1
procedure :: initialize_abstract
procedure :: initialize_logic
end type type1
contains
subroutine initialize_abstract(this,element)
class(type1), intent(inout) :: this
class(abstract), intent(in) :: element
this%x = element%x
end subroutine initialize_abstract
subroutine initialize_logic(this,element)
class(type1), intent(inout) :: this
class(logic), intent(in) :: element
this%x = element%y
end subroutine initialize_logic
subroutine initialize_type1(this,element)
class(type1), intent(inout) :: this
class(abstract), intent(in) :: element
select type (element)
type is (abstract)
call this%initialize_abstract(element)
type is (logic)
call this%initialize_logic(element)
class default
print*,"ERROR: Unknown type of the 'element' argument in 'initialize_type1'."
stop
end select
end subroutine initialize_type1
end module test2
Run Code Online (Sandbox Code Playgroud)
方法二(抽象类):
module test3
type type1
integer :: x
contains
procedure :: initialize => initialize_type1
end type type1
type, abstract :: veryAbstract
contains
procedure(init_t1), deferred :: initialize_t1
end type veryAbstract
abstract interface
subroutine init_t1(this,t1)
import veryAbstract
import type1
class(veryAbstract), intent(in) :: this
class(type1), intent(inout) :: t1
end subroutine
end interface
type, extends(veryAbstract) :: abstract
integer :: x
contains
procedure :: initialize_t1 => initialize_type1_from_abstract
end type abstract
type, extends(abstract) :: logic
integer :: y
contains
procedure :: initialize_t1 => initialize_type1_from_logic
end type logic
contains
subroutine initialize_type1(this,element)
class(type1), intent(inout) :: this
class(abstract), intent(in) :: element
call element%initialize_t1(this)
end subroutine initialize_type1
subroutine initialize_type1_from_abstract(this,t1)
class(abstract), intent(in) :: this
class(type1), intent(inout) :: t1
t1%x = this%x
end subroutine initialize_type1_from_abstract
subroutine initialize_type1_from_logic(this,t1)
class(logic), intent(in) :: this
class(type1), intent(inout) :: t1
t1%x = this%y
end subroutine initialize_type1_from_logic
end module test3
Run Code Online (Sandbox Code Playgroud)
测试程序:
PROGRAM test
use test2
!use test3
type(abstract) :: a1
type(logic) :: l1
type(type1) :: t1
type(type1) :: t2
a1%x = 1
l1%x = 2
l1%y = 7
call t1%initialize(a1)
call t2%initialize(l1)
print*,'t1%x: ',t1%x
print*,'t2%x: ',t2%x
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3542 次 |
| 最近记录: |