I have two derived types in a module, Interval
and Inrset
. Both have same functionality, however one operates on reals, the other on integers.
The problem being encountered is as follows
lib/interval.f:85:11:
Procedure :: eptset => inrval_set
1
Error: Argument 't' of 'inrval_set' with PASS(t) at (1)
must be of the derived-type 'inrset'
lib/interval.f:55:11:
Procedure :: eptset => inrval_set
1
Error: Argument 't' of 'inrval_set' with PASS(t) at (1)
must be of the derived-type 'interval'
Here is the Interval
derived type
Type Interval
Real (Real32) :: inf, sup
Contains
Procedure :: eptset => inrval_set
End Type Interval
And this is is the Intrset
derived type
Type Inrset
Integer (Int32) :: inf, sup
Contains
Procedure :: eptset => inrval_set
End Type Inrset
This shall be the common subroutine for setting inf
and sup
.
Subroutine inrval_set &
( &
t, inf, sup &
)
Class (*), Intent (InOut) :: t
Class (*), Intent (In) :: inf, sup
!!$--------------------------------------------------
!!$ Sets t% inf = inf; t% sup = sup
Select Type (t)
Type Is (Interval)
Call numtrf (t% inf, inf)
Call numtrf (t% sup, sup)
Type Is (Inrset)
Call numtrf (t% inf, inf)
Call numtrf (t% sup, sup)
End Select
End Subroutine inrval_set
Error messages are, admittedly, not always helpful. In this case it is a good prompt.
Your derived type Interval
has a type-bound procedure with binding name eptset
and interface the same as the procedure inrval_set
. This is your difficulty.
I imagine you have in mind a call like
type(Interval) range
call range%eptset(1._real32, 15._real32)
which is a reasonable goal.
However, you are relying on a passed-object dummy argument, so that in inrval_set
your first dummy argument t
is of dynamic type range
. This is flawed.
As the error message suggests, the interface for the type-bound procedure in Interval
must, because it doesn't have the NOPASS
attribute, have a dummy argument of type Interval
. A dummy argument of class(*)
is not such a thing.
You don't want to do this approach using NOPASS
.
You could, of course, have
call inrval_set(range, 1._real32, 15._real32)
as one option. But are there type-bound ways?
Yes.
You could consider templating. Or, have an (abstract) parent class. Or provide type-bound procedures with the appropriate interface - one for each type.
Essentially, you're repeating code in the select type
block, so you may as well repeat the code with generic/dynamic resolution instead.