Vincent Michaud-Rioux
Vincent Michaud-Rioux

Reputation: 45

How to point to a class method in fortran?

I have a module that defines a class with some attributes and a method (proc1) which is a function. Another module defines a function (proc2) that evaluates a function with one argument, given a pointer to that function and the argument. In the main program, I would like to define a function pointer (fun) which points to the class' method (proc1) such that evaluating fun(x) would be equivalent to evaluating obj1 % proc1(x). Is that possible?

My compiler, gfortran 7.3, complains that

Expected argument list at (1)

with the syntax below.

module objmod
   implicit none
   ! object with some data and a method
   type obj 
      real                  :: a, b, c
   contains
      procedure, pass(self) :: proc1
   end type obj

contains
   ! method which uses object and a variable
   pure real function proc1(self, var) 
      class(obj), intent(in) :: self
      real, intent(in)       :: var
      proc1 = var * (self % a + self % b + self % c)
   end function proc1

end module objmod

module funmod
   implicit none

contains
   ! function that evaluates fun(a), or does more complicated stuff
   real function proc2(funptr, a)
      procedure(real), pointer :: funptr
      real, intent(in)         :: a
      proc2 = funptr(a)
   end function proc2

end module funmod

program funPtr

   use objmod
   use funmod

   implicit none

   type(obj)                :: obj1
   real                     :: a, x
   procedure(real), pointer :: fun

   obj1 % a =  1.0
   obj1 % b =  2.0
   obj1 % c =  3.0
   a        = -1.5
   fun => obj1 % proc1 ! function pointer to fun(x) = proc1(obj1, x)

   x = proc2(fun, a)

   print *, x
end program funPtr

Upvotes: 2

Views: 332

Answers (1)

Steve Lionel
Steve Lionel

Reputation: 7267

No, you can't do this. The standard says, for a proc-target of pointer assignment:

C1030 (R1040) A procedure-name shall be the name of an internal, module, or dummy procedure, a procedure pointer, a specific intrinsic function listed in Table 16.2, or an external procedure that is accessed by use or host association, referenced in the scoping unit as a procedure, or that has the EXTERNAL attribute.

In your example, obj1%proc1 is none of these. You COULD pointer assign to proc1 (that is, the actual procedure and not the type component) if you gave fun an explicit interface. Of course, you lose the passed object aspect if you do this.

The issue is that a function pointer doesn't have the context of the type-bound procedure.

Upvotes: 3

Related Questions