Question

Je souhaite transmettre une procédure liée à un type (en tant que fonction externe) à une autre fonction comme suit :

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 produit donne cette erreur :

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

Mais ce que je peux faire c'est :

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

Je pense que le problème est lié à Passer des procédures liées au type comme arguments, mais je ne vois pas pour le moment comment les réponses qui s'y trouvent peuvent m'aider.

MODIFIER:

Un meilleur exemple qui (espérons-le) montre la difficulté :

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

MODIFIER II :Ok, les wrappers fonctionnent toujours en combinaison avec un pointeur :

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

Ce n’est certainement pas une belle solution mais au moins ça marche.

Était-ce utile?

La solution

Vous pouvez écrire un wrapper.Il s'agit de la version la plus simple.Nécessite de transmettre une fonction interne comme argument factice (F2008), mais vous pouvez également déclarer le wrapper dans un module, si le t peut être là.

Notez que j'ai modifié la déclaration de l'argument de procédure dans s à quelque chose de plus moderne - le bloc d'interface.

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

La raison de votre erreur est bien décrite dans les réponses à la question liée, vous ne pouvez pas transmettre les procédures liées au type comme vous l'avez essayé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top