Fortran类的异构数组 [英] Heterogeneous array of Fortran classes

查看:122
本文介绍了Fortran类的异构数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象类型和从他那里继承的几种类型.现在,我需要对这些继承类型的实例进行数组处理,但是我不确定,是否甚至可以在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

似乎不支持通过结构构造函数定义无限多态组件

does not appear to support definition of an unlimited polymorphic component via a structure constructor

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类的异构数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆