Frage

Ich möchte eine typgebundene Prozedur (als externe Funktion) wie folgt an eine andere Funktion übergeben:

module mod1
   implicit none

   type type1
      real :: a
      contains
      procedure,pass :: f
   end type

contains

   real function f(y,e)
      class(type1), intent(in) :: y
      real,intent(in) :: e
      f=y%a+e
   end function

end module

program test

   use mod1
   type(type1) :: t

   t%a=3e0
   write(*,*) s(t%f)

contains

   real function s(g)
      real,external :: g
      s=g(5e0)+2e0
   end function

end program

gfortran erzeugt diesen Fehler :

       write(*,*) s(t%f)
                       1
Error: Expected argument list at (1)

Aber was ich tun kann, ist:

program test

   t%a=3e0
   write(*,*) s(k)

contains

   real function s(g)
      real,external :: g
      s=g(5e0)+2e0
   end function

   real function k(e)
      real,intent(in) :: e
      k=3e0+e
   end function

end program

Ich denke, das Problem hängt damit zusammen Typgebundene Prozeduren als Argumente übergeben, aber ich sehe im Moment nicht, wie mir die Antworten dort helfen können.

BEARBEITEN:

Ein besseres Beispiel, das (hoffentlich) die Schwierigkeit zeigt:

module mod2
   implicit none
contains

   real function s(g)
       interface
        real function g(x)
          real, intent(in) :: x
        end function
      end interface

      s=g(5e0)+2e0
   end function
end module

module mod1
   use mod2

   type type1
      real :: a
      contains
      procedure,pass :: f
      procedure,pass :: h
   end type

contains

   real function f(y,e)
      class(type1), intent(in) :: y
      real,intent(in) :: e
      f=y%a+e
   end function

   real function h(y)
      class(type1), intent(inout) :: y
      h=s(y%f)
   end function
end module

program test

use mod1
   type(type1) :: t

   t%a=3e0
   write(*,*) t%h
end program

BEARBEITEN II:Ok, die Wrapper funktionieren immer noch in Kombination mit einem Zeiger:

module mod2
   implicit none
contains

   real function s(g)
       interface
        real function g(x)
          real, intent(in) :: x
        end function
      end interface

      s=g(5e0)+2e0
   end function
end module 

module mod1 
   use mod2

   type type1
      real :: a
      contains
      procedure,pass :: f
      procedure,pass :: h
   end type

   class(type1),pointer :: help_w

contains

   real function f(y,e)
      class(type1), intent(in) :: y
      real,intent(in) :: e
      f=y%a+e
   end function

   real function h(y)
      class(type1), intent(inout),target :: y
      help_w => y
      h=s(wrap) 
   end function

   function wrap(x)
      real,intent(in) :: x
      wrap=help_w%f(x)
   end function 
end module

program test

use mod1
   type(type1) :: t

   t%a=3e0
   write(*,*) t%h()
end program

Dies ist sicherlich keine schöne Lösung, aber zumindest funktioniert es.

War es hilfreich?

Lösung

Sie können einen Wrapper schreiben.Dies ist die einfachste Version.Erfordert die Übergabe einer internen Funktion als Dummy-Argument (F2008), aber Sie könnten den Wrapper auch in einem Modul deklarieren, wenn die t kann dort sein.

Hinweis: Ich habe die Deklaration des Prozedurarguments in geändert s zu etwas Modernerem - dem Schnittstellenblock.

program test
   use mod1
   type(type1) :: t

   t%a=3e0
   write(*,*) s(wrap)

contains

   real function s(g)
      interface
        real function g(x)
          real, intent(in) :: x
        end function
      end interface

      s=g(5e0)+2e0
   end function

   function wrap(x)
     real, intent(in) :: x
     wrap = t%f(x)
   end function

end program

Der Grund für Ihren Fehler ist in den Antworten auf die verknüpfte Frage gut beschrieben. Sie können typgebundene Prozeduren nicht so übergeben, wie Sie es versucht haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top