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

overriding procedure -- extended type arguments

elwong
Beginner
932 Views
I'm trying to write a subroutine for an extended type to copy data from one object to another.
However, it seems that what I'm trying to do isn't legal:

>> gfortran -c test1.f90
test1.f90:23.14:

procedure :: copy => t1copy
1
Error: Types mismatch for dummy argument 'b' of 'copy' (1) in respect to the overridden procedure

I guess the second argument 'b' must be exactly the same type, in this case class(t0) and not t1, the extension. Does anyone have suggestions on what I could do instead?

[fortran]module t0mod
  type :: t0
     integer :: i
   contains
     procedure :: copy => t0copy
  end type t0
contains

  subroutine t0copy ( a, b )
    class(t0) :: a, b
    b%i = a%i
  end subroutine t0copy

end module t0mod


module t1mod
  use t0mod

  type, extends(t0) :: t1
     integer :: j
   contains
     procedure :: copy => t1copy
  end type t1

contains

  subroutine t1copy ( a, b )
    class(t1) :: a, b
    b%j = a%j
  end subroutine t1copy

end module t1mod
[/fortran]
0 Kudos
3 Replies
elwong
Beginner
932 Views
I should add I get the same error from ifort, which leads me to believe what I have is not legal.

0 Kudos
Hirchert__Kurt_W
New Contributor II
932 Views
The typical solution involves the use of the SELECT TYPE construct. Here's one possible solution:

subroutine t1copy ( a, b )
class(t1) :: a
class(t0) :: b
select type(b)
class is (t1)
b%j = a%j
class default
call a%t0%copy(b)
end select type
end subroutine

If you don't want to revert to the class(t0) copy when b is not class(t1), you could generate some kind of error message in the CLASS DEFAULT block instead.

I note that, as written, your class(t0) copy copies the i component, and your class(t1) copy copies the j component, but not the i component. This seems an atypical choice. If you wanted your class(t1) copy to also copy the class(t0) components, you need to make that explicit. For that, the body of t1copy might look more like

call a%t0%copy(b) ! copy the base components
select type(b) ! if b also is class(t1), copy the t1 components
class is (t1)
b%j = a%j
end select type

In this version, I left out the CLASS DEFAULT because it wasn't going to do anything, and that's what happens if it is omitted.


Does any of this help?

-Kurt
0 Kudos
elwong
Beginner
932 Views
Thanks for that nice solution. I was ready to try to overload the = operator, but this is much better.

As for not copying the i component in class(t1)...I just wrote the example quickly and neglected to copy i. The real code was too complicated to post here, but there I do call the parent's copy subroutine.
0 Kudos
Reply