Deferred procedures are those functions/subroutines that will be later implemented in a specific derived type. For instance, It can only be declared on abstract derived types.
To illustrate it, our problem requires a generic class that enforces the equal (==) property. Fortran classes must implement/overload the generic ‘==’ so it is possible to compare them. This can be usefull when using unlimited polymorphic types -class(*)-.
The code below declares a new generic class called eqObject_abs. When extended it enforces to implement the equal property.
type, abstract :: eqObject_abs !< equal unlimited polymorphic type
!< for non basic types
contains
procedure(iface_eq_object), deferred :: eq_object
generic :: operator(==) => eq_object
end type eqObject_abs
Aside from the deferred statement, eq_object subroutine has attached an interface called iface_eq_object. It is mandatory when a type is deferred.
An abstract interface tells which procedure/function signature should expect when the type is extended. So all implementations will follow this header.
Note it requires to import any non basic type.
abstract interface
logical function iface_eq_object(self, other)
!< true if self and other are not the same
import eqObject_abs
!< it will evolve according to subtype
class(eqObject_abs), intent(in) :: self
class(eqObject_abs), intent(in) :: other
end function iface_eq_object
end interface
Later on, define a new derived type by extending the abstract object:
type, extends(eqObject_abs) :: stringEQ
character(:), allocatable :: chars
contains
procedure :: eq_object => eq_object_StringEq
end type
Finally, declare its deferred type:
logical function eq_object_stringEq(self, other)
!< true if self and other are the same type and contains the same chars
class(stringEq), intent(in) :: self
class(eqObject_abs), intent(in) :: other
class(stringEq), pointer :: pstringEq
select type(obj => other) !< cast type
type is (stringEq)
pStringEq => obj
class default
! error (or false), different types
write(*,*) "Unexpected type found"
stop 1
end select
eq_object_stringEq = (self % chars == pStringEq % chars)
end function eq_object_stringEq
Regarding the abstract interface, the self argument must be adapted according to the new class where it belongs (stringEq vs eqObject_abs).
Its implementation is not obvious and it requires a certain degree of knowledge about Fortran.