سؤال

أريد تمرير إجراءات مرتبطة بالنوع (كوظيفة خارجية) إلى وظيفة أخرى على النحو التالي:

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 هذا الخطأ:

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

لكن ما يمكنني فعله هو:

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

أعتقد أن المشكلة مرتبطة بـ تمرير الإجراءات المرتبطة بالنوع كوسائط, ، لكنني لا أرى في الوقت الحالي كيف يمكن أن تساعدني الإجابات هناك.

يحرر:

مثال أفضل يوضح (نأمل) الصعوبة:

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

التعديل الثاني:حسنًا، لا تزال الأغلفة تعمل مع المؤشر:

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

هذا بالتأكيد ليس حلاً جميلاً ولكنه على الأقل يعمل.

هل كانت مفيدة؟

المحلول

يمكنك كتابة المجمع.هذه هي النسخة الأكثر وضوحا.يتطلب تمرير وظيفة داخلية كوسيطة وهمية (F2008)، ولكن يمكنك إعلان المجمع في وحدة نمطية أيضًا، إذا كان t يمكن النحل هناك.

لاحظ أنني قمت بتغيير إعلان وسيطة الإجراء في s إلى شيء أكثر حداثة - كتلة الواجهة.

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

تم توضيح سبب الخطأ بشكل جيد في إجابات السؤال المرتبط، ولا يمكنك تمرير إجراءات ربط النوع بالطريقة التي حاولت بها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top