- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Good evening,
I have a problem using polymorphic variables and I appreciate any help I can get from you. The problem is that when I allocate a type to a polymorphic varibale, this variable does not recognize the properties of that type. Please have a look at the simple example I made.
Consider an object shape with two childs named rec and circ. Another object which is named usedshape has a polymorphic variable of class (shape). Now for different occasions, I want to assign, rect or circ to useshape%shape and I expect that useshape%shape has the properties (and functionalities) of circ or rect whichever is assigned. However, it does not work for me. I also tried defining the polymorphic variable by class (*) which should be able to assign any type to it, but it does not work
Any comments on this problem is appreciate. If this is impossible, how can I get around this problem?
Thank you very much for your time
* I am using Intel fortran 2013 (Compiling with Intel(R) Visual Fortran Compiler XE 12.0.0.104 [IA-32])
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can't do much of anything with an unlimited polymorphic unless you are inside a SELECT TYPE construct. Even if you have just allocated it to a type, you can't treat it as an object of that type unless you're inside a SELECT TYPE case for that type.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanx Steve for the propmt answer. Do u have any comment on how can I get this flexibility that i need in the code? I have an object similar to useshape which it contains another object shape which should be polymorohic, meaning get the objects of differnet kind like circ or rect. Any comment on how to design and code such a situation would be very appreciated.
Thank you very much in advance
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've tried including the select type in the example but still can't get it to compile
[fortran]
select case (var)
case (1)
allocate ( rect :: useshape_test%SH )
select type(useshape_test%SH)
type is (rect)
useshape_test%SH%rsize = 4
allocate (useshape_test%SH%rprop(1:4))
end select
case (2)
allocate (circ :: useshape_test%SH)
select type(useshape_test%SH)
type is (circ)
useshape_test%SH%rsize = 4
allocate (useshape_test%SH%rprop(1:4))
end select
useshape_test%SH%csize = 10
allocate (useshape_test%SH%cprop(1:10))
end select
[/fortran]
C:\Program Files (x86)\Intel\Composer XE 2013.149>ifort /c source1.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.1.0.149 Build 20130118
Copyright (C) 1985-2013 Intel Corporation. All rights reserved.
source1.f90(80): error #8253: If selector expression in SELECT TYPE is not a named variable, associate-name=> shall appear.
select type(useshape_test%SH)
----^
source1.f90(82): error #6460: This is not a field name that is defined in the encompassing structure. [RSIZE]
useshape_test%SH%rsize = 4
-------------------------^
source1.f90(83): error #6460: This is not a field name that is defined in the encompassing structure. [RPROP]
allocate (useshape_test%SH%rprop(1:4))
-----------------------------------^
source1.f90(87): error #8253: If selector expression in SELECT TYPE is not a named variable, associate-name=> shall appear.
select type(useshape_test%SH)
----^
source1.f90(92): error #6460: This is not a field name that is defined in the encompassing structure. [CSIZE]
useshape_test%SH%csize = 10
---------------------^
source1.f90(93): error #6460: This is not a field name that is defined in the encompassing structure. [CPROP]
allocate (useshape_test%SH%cprop(1:10))
-------------------------------^
compilation aborted for source1.f90 (code 1)
C:\Program Files (x86)\Intel\Composer XE 2013.149>
What have I done wrong?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The error messages are rather clear to me - did you not understand them?
The following compiles
[fortran]
module testing
implicit none
private
public :: shape , circ , rect , useshape
type shape
character(4) :: s_name
end type shape
type , extends (shape) :: rect
integer :: rsize
real , dimension(:) , allocatable :: rprop
contains
procedure sumprop => rect_sumprop
end type
type , extends (shape) :: circ
integer :: csize
real , dimension(:) , allocatable :: cprop
contains
procedure sumprop => circ_sumprop
end type
type useshape
character(4) :: us_name
class (*) , allocatable :: SH
! class (shape) , allocatable :: SH
contains
procedure :: Comp
end type
contains
function rect_sumprop(this)
implicit none
real :: rect_sumprop
class (rect) :: this
integer :: i
rect_sumprop = 0.
do i=1 , this%rsize
rect_sumprop = rect_sumprop + this%rprop(i)
end do
end function
function circ_sumprop(this)
implicit none
real :: circ_sumprop
class (circ) :: this
integer :: i
circ_sumprop = 0.
do i=1 , this%csize
circ_sumprop = circ_sumprop + this%cprop(i)
end do
end function
function comp(this)
implicit none
real :: comp
class (useshape) :: this
comp = 0.
! comp = this%SH%sumprop()
end function
end module testing
program main
use testing
implicit none
integer :: var
type (useshape) :: useshape_test
var = 2
select case (var)
case (1)
allocate ( rect :: useshape_test%SH )
select type(selector=>useshape_test%SH)
type is (rect)
selector%rsize = 4
allocate (selector%rprop(1:4))
end select
case (2)
allocate (circ :: useshape_test%SH)
select type(selector=>useshape_test%SH)
type is (circ)
selector%csize = 4
allocate (selector%cprop(1:4))
end select
end select
end program
[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanx for your comment Steve. I got the idea of polymorphic variables I guess. However, the code you provided does not run for var=2 correctly (although it does compile but when debugging with var=2, the selector%csize is not defined) !!! However, it does work for var=1. Is this a problem with the compiler??
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How does it "not run"? It seems to run fine for me.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh, you are right, My problem was using selector outside the select type construct. It does run.
however, is there a way that I point a polymorphic pointer (like useshape%SH) to any of circ or rect objects and then use it without a select type construct. For example, in the main program I need to do :
program main
use testing
implicit none
integer :: var
type (useshape) :: useshape_test
var = 1
select case (var)
case (1)
allocate ( rect :: useshape_test%SH )
select type(selector=>useshape_test%SH)
type is (rect)
selector%rsize = 4
allocate (selector%rprop(1:4))
selector%rprop(1:4) = 3
end select
case (2)
allocate (circ :: useshape_test%SH)
select type(selector=>useshape_test%SH)
type is (circ)
selector%csize = 5
allocate (selector%cprop(1:5))
selector%cprop(1:5) = 10
end select
end select
select type (selector=>useshape_test%SH)
type is (circ)
print*, selector%sumprop()
type is (rect)
print*, selector%sumprop()
end select
read*
end program
Instead I would like to able to do sth like:
print*, useshape_test%SH%sumprop()
With the select type construct, verytime that I use a procedure of the object assigned to useshape_test%SH, I need to use a select type construct, which results in repreating a piece of code several times !! Is the a way around this?
thank you very much
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No. The language requires the SELECT TYPE in order for you to name any of the dynamic type's components. Maybe you can use type extension rather than unlimited polymorphic?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The OP should also have a look at the SOURCE specifier in an allocate statement. This is shown below, using a structure constructor to specify the initial value of the components in the allocated object. Instead of the structure constructor you could have a function that constructs your Rect (or circle) object just the way you want...
[fortran]ALLOCATE( useshape_test%SH, SOURCE=Rect( RSIZE=4, RPROP=[0.0, 0.0, 0.0, 0.0]))[/fortran]
For the most recent query - put aspects that are common between the types into the parent type - for instance both types have a sumpop binding - is that going to be common to all shapes?. If so, make that a binding of the parent shape type and override that binding in the extensions. You can then call that binding on any object that has a declared type of Shape, without needing to use SELECT TYPE.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you IanH and Steve for your comments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran]
select type(selector=>useshape_test%SH)
[/fortran]
I didn't realize that useshape_test%SH was not a named variable in this context and that therefore the associate-name was required so thanks for that.
I still haven't got to grips with this new moderation of this forum. I posted yesterday morning (uk time) and watched for my post during the afternoon but nothing appeared. This morning I arrive and there seems to have been a whole conversation which has moved the thread's topic on. I guess you had a reason for changing from the captcha scheme but at least with that my posts went up at the right time. If we have to wait for human moderators in one timezone then the inherent latency will severely limit the usefulness of this forum. 09:33.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I hope that the moderation issue will be resolved soon.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page