2

I have a pair of functions that perform the same operation, say, calculating whether or not their input is greater than zero, but one operates on a real input while the other operates on an integer input. As such, I've wrapped them in an interface.

However, now I want to be able to create a procedure pointer to these functions so that I can pass it to another function for execution.

module validation_module
  implicit none

  ! I want to point to this interface.
  interface greater_than_zero
    procedure :: gt0_int, gt0_real
  end interface

  contains

    function gt0_int(i)
      logical :: gt0_int
      integer :: i

      gt0_int = i > 0
    end function

    function gt0_real(r)
      logical :: gt0_real
      real :: r

      gt0_real = r > 0
    end function

end module

The closest that I've been able to come is using the suggestion that M.S.B. made in: How to alias a function name in Fortran and the example code that is up on the Fortran Wiki, but neither of those examples used functions that had different types for their arguments.

My best attempt uses two different abstract interfaces, one for each type, but that kinda undoes the work of the one interface because one abstract interface must be made for each type. Plus, it fails to compile with:

   51 |   ptr%ptr_int => greater_than_zero
      |                 1
Error: Interface mismatch in procedure pointer assignment at (1): 'greater_than_zero' is not a function

Closest attempt:

module validation_module
  implicit none

  type func_ptr
    procedure (validation_integer), pointer, nopass :: ptr_int
    procedure (validation_real), pointer, nopass :: ptr_real
  end type

  abstract interface
    function validation_integer(i)
      logical :: validation_integer
      integer :: i
    end function
  end interface

  abstract interface
    function validation_real(r)
      logical :: validation_real
      real :: r
    end function
  end interface

  interface greater_than_zero
    procedure :: gt0_int, gt0_real
  end interface

  contains

    function gt0_int(i)
      logical :: gt0_int
      integer :: i

      gt0_int = i > 0
    end function

    function gt0_real(r)
      logical :: gt0_real
      real :: r

      gt0_real = r > 0
    end function

end module

program main
  use :: validation_module, only : func_ptr, greater_than_zero
  implicit none

  type(func_ptr) :: ptr

  ptr%ptr_int => greater_than_zero

end program

How can I effectively make a pointer to an interface?

NolantheNerd
  • 338
  • 3
  • 10

0 Answers0