问题描述
我有一个抽象类型和从他那里继承的几种类型.现在,我需要对这些继承类型的实例进行数组处理,但是我不确定,是否甚至可以在Fortran中使用.
I have an abstract type and several types which inherit from him. Now I need to make an array of instances of those inherited types, but I'm not sure, if it's even possible in Fortran.
我尝试创建一些包装类型,例如在在Fortran中创建异构数组.
I've tried to make some wrapper type, like in Creating heterogeneous arrays in Fortran.
module m
implicit none
type, abstract :: a
integer, public :: num
end type a
type, extends(a) :: b
end type b
type, extends(a) :: c
end type c
type :: container
class(*), allocatable :: ptr
end type
end module m
program mwe
use m
type(b) :: b_obj
class(*), allocatable :: a_arr(:)
b_obj = b(1)
allocate(container :: a_arr(3))
a_arr(1) = container(b_obj)
end program mwe
但是我遇到了这个错误:
But I'm getting this error:
test3.f90:28:25:
a_arr(1) = container(b_obj)
1
Error: Can't convert TYPE(b) to CLASS(*) at (1)
我做错了什么?还是还有其他正确的方法呢?
What am I doing wrong? Or is there any other, correct way to do it?
我根据francescalus的答案对代码进行了相应的
I edited the code accordingly to francescalus's answer:
program mwe
use m
type(b) :: b_obj
type(c) :: c_obj
type(container), allocatable :: a_arr(:)
integer :: i
b_obj = b(1)
c_obj = c(2)
allocate(container :: a_arr(3))
a_arr(1)%ptr = b(1)
a_arr(2)%ptr = c(3)
a_arr(3)%ptr = c(1000)
do i=1,3
write(*,*) a_arr(i)%ptr%num
end do
end program mwe
我又遇到另一个错误:
test3.f90:36:35:
write(*,*) a_arr(i)%ptr%num
1
Error: ‘num’ at (1) is not a member of the ‘__class__STAR_a’ structure
推荐答案
作为IanH 进行了评论在概述您采用的方法时,应使用gfortran的当前版本
As IanH commented when outlining the approach you take, the then current version of gfortran
container(b_obj)
就是这样.因此,撇开您是否仍然要解决此问题,也许有人仍然希望允许较早版本/其他编译器使用该代码.
container(b_obj)
is such a thing. So, leaving aside whether you are still coming up against this problem, one may be interested in still allowing older versions/other compilers to use the code.
另一种方法是不对容器的元素使用构造函数.相反,单个组件可以直接在任务中使用:
An alternative approach is not to use a constructor for the element of your container. Instead the single component can feature directly in an assignment:
use m
type(container) a_arr(3) ! Not polymorphic...
a_arr%ptr = b(1) ! ... so it has component ptr in its declared type
end mwe
自然地,我们仍然具有容器类型多态的组件,因此任何尝试引用/定义/等操作的组件都将受到这些各种限制.在您的问题中,您有无限多态的组件,但是我看到您首先谈论的是将容器的考虑限制在扩展第一种类型的元素上.与其将容器组件声明为无限多态,不如将其声明为a
:
type :: container
class(a), allocatable :: ptr
end type
这足以解决以下问题
do i=1,3
write(*,*) a_arr(i)%ptr%num
end do
因为num
是声明的a_arr(i)%ptr
类型的组件(即a
).通常,这不是完整的解决方案,因为
because num
is a component of the declared type of a_arr(i)%ptr
(that is., a
). In general, it isn't the complete solution because
do i=1,3
write(*,*) a_arr(i)%ptr%num_of_type_b
end do
不起作用(对于num_of_type_b
扩展类型的组件).在这里,您必须使用通常的技巧(定义的输入/输出,动态分辨率,select type
等).这些超出了此答案的范围,可能会发现许多其他问题.
wouldn't work (with num_of_type_b
a component in the extending type). Here you have to use the usual tricks (defined input/output, dynamic resolution, select type
and so on). Those are beyond the scope of this answer and many other questions may be found covering them.
这篇关于Fortran类的异构数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!