- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am having some problems with polymorphic type definitions. I made a slight change to a sample program that Steve Lionel posted years ago:
program PolyArray
implicit none
type basetype
integer :: i=1
end type basetype
type, extends(basetype) :: exttype1
integer :: j=2
end type exttype1
type, extends(exttype1) :: exttype2
integer :: k=3
end type exttype2
type arraytype
class(basetype), allocatable :: comp
end type arraytype
type(arraytype), dimension(3) :: ary
integer :: i
allocate (basetype::ary(1)%comp)
allocate (exttype1::ary(2)%comp)
allocate (exttype2::ary(3)%comp)
do i=1,3
select type (st=>ary(i)%comp)
type is (basetype)
print 101,i,"basetype"
print *,ary(i)%comp%i
type is (exttype1)
print 101,i,"exttype1"
print *,ary(i)%comp%j
type is (exttype2)
print 101,i,"exttype2"
print *,ary(i)%comp%k
class default
print 101,i,"unknown"
end select
101 format ("The dynamic type of ary(",i0,")%comp is ",A)
end do
end program PolyArray
When I try to compile this code with the latest oneAPI Fortran compiler (ifx version 2021.3.0 Beta), I get the error statements
PolyArray.f90(35): error #6460: This is not a component name that is defined in the encompassing structure. [J]
print *,ary(i)%comp%j
--------------------------------^
PolyArray.f90(38): error #6460: This is not a component name that is defined in the encompassing structure. [K]
print *,ary(i)%comp%k
--------------------------------^
compilation aborted for PolyArray.f90 (code 1)
This may not be a problem with the compiler, but rather my understanding of polymorphic derived types. The variable comp is of class(basetype), but I thought that it should "inherit" all the extended type variables as well. That is, in this example, the variable i in the basetype is recognized, but j and k in the type extensions are not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You want this instead:
select type (st=>ary(i)%comp)
type is (basetype)
print 101,i,"basetype"
print *,st%i
type is (exttype1)
print 101,i,"exttype1"
print *,st%j
type is (exttype2)
print 101,i,"exttype2"
print *,st%k
class default
print 101,i,"unknown"
end select
Since you created an associate name, that's the name that has the selected type.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You want this instead:
select type (st=>ary(i)%comp)
type is (basetype)
print 101,i,"basetype"
print *,st%i
type is (exttype1)
print 101,i,"exttype1"
print *,st%j
type is (exttype2)
print 101,i,"exttype2"
print *,st%k
class default
print 101,i,"unknown"
end select
Since you created an associate name, that's the name that has the selected type.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As a quick follow-up, how does one invoke, say, ary(2)%comp%j outside of the select type construct?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can't, because the "declared type" of comp is basetype, which doesn't have a j component.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page