اكتب الإجراء المنضم كوسائط
-
20-12-2019 - |
سؤال
أريد تمرير إجراءات مرتبطة بالنوع (كوظيفة خارجية) إلى وظيفة أخرى على النحو التالي:
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
تم توضيح سبب الخطأ بشكل جيد في إجابات السؤال المرتبط، ولا يمكنك تمرير إجراءات ربط النوع بالطريقة التي حاولت بها.