When you try to overload subroutines by means of generic interfaces, or combining modules or through type-bound procedures, one has to take into account that any of the procedures with the same generic name must have distinguishable or incompatible arguments.
When using unlimited polymorphic entities, you can quickly run in such problems as demonstrated in this incredible educational example:
INTERFACE foobar
SUBROUTINE foo(x)
INTEGER :: x
END SUBROUTINE foo
SUBROUTINE bar(x)
CLASS(*) :: x
END SUBROUTINE bar
END INTERFACE foobar
Here, foo(x)
conflicts with bar(x)
as the argument of bar
can also be an INTEGER
.
This particular problem can be resolved using the SELECT TYPE
construct in a new subroutine which replaces the generic interface:
SUBROUTINE foobar(x)
CLASS(*) :: x
SELECT TYPE (x)
TYPE IS INTEGER
CALL foo(x)
CLASS default
CALL bar(x)
END SELECT
END SUBROUTINE foobar
However, sometimes such constructs can become tedious and unwanted.
Are there other ways to implement such specialisation without the usage of the SELECT TYPE
construct?
I think above usage of the SELECT TYPE construct is best way to implement such requirement. As per Fortran 2018 specification usage of INTERFACE foobar in above program is NOT specification confirming as integer x and class(*) x are TKR compatible. Compiler should generate compile time error for above program. I think there is no better workaround other than replacing generic interface by a procedure and use select type construct to call specific procedures.
Restrictions on generic declarations:
Two dummy arguments are distinguishable if: they are both data objects or known to be functions, and neither is TKR compatible with the other.
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