I'm trying to compile the Fortran module below (using gfortran 7.2.0). The point is to define a derived type that in turn contains two instances of the derived type bspline_3d
from the bspline-fortran library (https://github.com/jacobwilliams/bspline-fortran). I then want to define a type-bound procedure that will in turn call the type-bound evaluate
procedure of both of those types, and return the result as an array with two elements.
When I try to compile the module below, I get an error message saying
procedure :: evaluate => evaluate_2d
1
Error: Non-polymorphic passed-object dummy argument of 'evaluate_2d' at (1)
I understand absolutely nothing of the error message.
I managed to compile the simple example program found here: http://fortranwiki.org/fortran/show/Object-oriented+programming and as far as I can tell, the only difference is that in my case, the "passed-object" (this
) does itself have derived-type member variables (type(bspline_3d) :: fvx, fvy
), which in turn probably contain all sorts of stuff.
module interpolator_module
use bspline_module
use parameters, only: WP
implicit none
private
public :: interpolator
type :: interpolator
type(bspline_3d) :: fvx, fvy
contains
private
procedure :: evaluate => evaluate_2d
end type interpolator
contains
function evaluate_2d(this, X, t) result(V)
implicit none
! inputs
type(interpolator), intent(inout) :: this
real(WP), dimension(2), intent(in) :: X
real(WP), intent(in) :: t
! output
real(WP), dimension(2) :: V
! local variables
integer :: iflag
integer, parameter :: d = 0
call this%fvx%evaluate(X(1), X(2), t, d, d, d, V(1), iflag)
call this%fvy%evaluate(X(1), X(2), t, d, d, d, V(2), iflag)
end function
end module interpolator_module
For a type-bound procedure defined like
type my_type
contains
procedure :: proc
end type
the type-bound procedure has a passed argument. That is, when
type(my_type) my_obj
call my_obj%proc
is used, the object my_obj
is in the argument list. With proc
defined as
subroutine proc(me)
type(my_type) me ! Not correct
end subroutine
then call my_obj%proc
is like call proc%(my_obj)
.1 That's the "passed-object dummy argument" part of the error message.
In the definition of proc
above, the passed-object dummy argument type(my_type) me
is non-polymorphic. You can read about polymorphism elsewhere, but to answer the question: a passed-object dummy argument may not be non-polymorphic. It must be polymorphic, declared using class(my_type) me
:
subroutine proc(me)
class(my_type) me ! Polymorphic, declared type my_type
end subroutine
This means that an object of type my_type
or of a type extending my_type
may be passed. This is a requirement of the Fortran language.
In short: change your
type(interpolator), intent(inout) :: this
to
class(interpolator), intent(inout) :: this
To complicate matters, older versions of gfortran, for example, understood type-bound procedures before understanding polymorphism. This means that there are some examples of erroneous use of non-polymorphic passed-objects around.
1 I've deliberately left the binding name as proc
the same as the procedure's name. In the context of the question it would be call my_obj%evaluate(...)
like call evaluate_2d(my_obj, ...)
.
The passed dummy argument this
must always be polymorphic. That means it must be
class(interpolator), intent(inout) :: this
and not
type(interpolator), intent(inout) :: this
That is a fundamental requirement for type-bound procedures. Otherwise you could not usse the procedure for extended types (children).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With