Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29361 Discussions

Polymorphic array - Assign elements of different types

Felix_R_2
Beginner
690 Views

Hello Forum!

Let's say I have a supertype like this

    type, public :: supertype
        character(len=:), allocatable :: id
        character(len=:), allocatable :: type

        contains
    end type

and multiple subtypes like these

    type, public, extends(supertype) :: subtype1
        type(membertype) :: firstMember
        contains
            procedure :: setFirstMember
            procedure :: getFirstMember
   end type

and then I want an Array like

class(supertype), dimension(:), allocatable :: array

where I can put objects of different subtypes and get them out again, so they retain their subtype when it comes to a "select type" later.

Is this possible? I understand I have to assign the elements to the array by sourced allocation but when I try to assign a value to the third array entry with

type(subtype1) :: subtype1Object

allocate(array(3), source = subtype1Object)

I do not only assign a type and value to array entry 3 but get an array of size 3 with all the entries being copies of subtype1Object.

I hope someone can help me, unfortunately there isn't a lot of literature on Fortran OO out there.

0 Kudos
1 Reply
IanH
Honored Contributor III
690 Views

You need a wrapper type.

TYPE supertype_element
   CLASS(supertype), ALLOCATABLE :: item
END TYPE supertype_element

! Allocatable only to allow its length to vary at runtime.
TYPE(supertype_element), ALLOCATABLE :: array(:)
ALLOCATE(array(3))

! code defining array(1)%item, array(2)%item, then...
ALLOCATE(array(3)%item, SOURCE=subtype1Object)

 

Be mindful that if you start assigning objects of type supertype_element, then you probably need to be using ifort version 16 or later.

 

(Edit to note that you don't have to used source allocation... you can allocate the %item component to the right dynamic type and then select type on it to complete its initialisation; or you can define a non-polymorphic allocatable and then move_alloc it into the %item component.  With F2008 you can assign directly to polymorphic components.)

0 Kudos
Reply