问题描述
在我们学习了如何在Fortran中将子例程名称作为参数传递。我们如何在类结构中做到这一点?
接下来的代码使用GNU Fortran(GCC)5.1.0产生以下编译错误:
gfortran -Wall -Wextra -Wconversion -Og -pedantic -fcheck = bounds -fmax-errors = 5 class_pass.f08
myClass.f08:44:30:
class(test),target :: me
1
错误:在定义之前使用(1)处的派生类型'test'
myClass.f08:9:21:
procedure,public :: action => action_sub
1
错误:在(1)
myClass.f08:40:36:
类中的'action_sub'的非多态传递对象伪参数测试),target :: me
1
错误:(1)处的CLASS变量'me'必须是虚拟的,可分配的或指针
(null):0:被以前的错误困惑, out
主程序如下。它包含一个用于诊断的例程 check
。
$ b
include'myClass .f08'
程序class_pass
使用myClass
隐式无
类型(测试):: myTest
call myTest %check()
call myTest%action(square_sub)
end program class_pass
模块:
module myClass
隐式无
type :: test
real :: x,y
包含
private
procedure,public :: action => action_sub
procedure,public :: square => square_sub
procedure,public :: double => double_sub
过程,public :: check => check_sub
结束类型测试
private :: action_sub
private :: square_sub
private :: double_sub
private :: check_sub
包含
子程序square_sub(me)
class(test),target :: me
me%y = me%x ** 2
end子程序square_sub
子程序double_sub(me)
class(test),target :: me
me%y = me%x * 2
end subroutine double_sub
子程序check_sub(me)
class(test),target :: me $ b $ me%x = 5.0
call double_sub(me)
print *,'x = ',me%x,',y =',me%y
结束子程序check_sub
子程序action_sub(子)
class(test),target :: me
接口mySub
子例程sub(me)
class(test),target :: me
end subroutine su b
end interface mySub
call sub(me)
print *,'x =',me%x'',y =',me%y
结束子程序action_sub
结束模块myClass
非常感谢@ vladimir F为原始解决方案和技巧。 您的错误是由于您的过程中缺少参数 action_sub
和其他一些小事情。这个过程通过
procedure,public :: action =>绑定到派生类型。 action_sub
,默认情况下,多态类变量作为第一个参数传递给 action_sub
。您已在其他类型的绑定过程中正确说明了这一点,但在此过程中没有这样做。您还需要将接口块中的派生类型导入到 action_sub
中,以便在那里使用该类型。这个过程的修改版本可以让你的模块正确编译:
子程序action_sub(me,sub)
class (test),target :: me
interface mySub
子例程sub(me)
import test
class(test),target :: me
end子程序sub
end interface mySub
call sub(me)
print *,'x =',me%x'',y =',me%y
结束子程序action_sub
接下来,在你的主程序中: >
call myTest%action(square_sub)
以便引用 square_sub
这里您需要在您的模块中公开该过程。从模块过程中删除 private
属性后,代码将编译并运行:
x = 5.00000000,y = 10.0000000
x = 5.00000000,y = 25.0000000
In How to pass subroutine names as arguments in Fortran? we learned how to pass subroutine names as arguments in Fortran. How can we do this inside a class structure?
The ensuing code produces the following compilation error using GNU Fortran (GCC) 5.1.0:
gfortran -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5 class_pass.f08
myClass.f08:44:30:
class ( test ), target :: me
1
Error: Derived type ‘test’ at (1) is being used before it is defined
myClass.f08:9:21:
procedure, public :: action => action_sub
1
Error: Non-polymorphic passed-object dummy argument of ‘action_sub’ at (1)
myClass.f08:40:36:
class ( test ), target :: me
1
Error: CLASS variable ‘me’ at (1) must be dummy, allocatable or pointer
(null):0: confused by earlier errors, bailing out
The main routine follows. It includes a routine check
used as a diagnostic.
include 'myClass.f08'
program class_pass
use myClass
implicit none
type ( test ) :: myTest
call myTest % check ()
call myTest % action ( square_sub )
end program class_pass
The module:
module myClass
implicit none
type :: test
real :: x, y
contains
private
procedure, public :: action => action_sub
procedure, public :: square => square_sub
procedure, public :: double => double_sub
procedure, public :: check => check_sub
end type test
private :: action_sub
private :: square_sub
private :: double_sub
private :: check_sub
contains
subroutine square_sub ( me )
class ( test ), target :: me
me % y = me % x ** 2
end subroutine square_sub
subroutine double_sub ( me )
class ( test ), target :: me
me % y = me % x * 2
end subroutine double_sub
subroutine check_sub ( me )
class ( test ), target :: me
me % x = 5.0
call double_sub ( me )
print *, 'x = ', me % x, ', y = ', me % y
end subroutine check_sub
subroutine action_sub ( sub )
class ( test ), target :: me
interface mySub
subroutine sub ( me )
class ( test ), target :: me
end subroutine sub
end interface mySub
call sub ( me )
print *, 'x = ', me % x, ', y = ', me % y
end subroutine action_sub
end module myClass
Many thanks to @Vladimir F for the original solution and tips.
Your errors are due to missing parameters in your procedure action_sub
and a few other minor things. This procedure is bound to your derived type via
procedure, public :: action => action_sub
and by default the polymorphic class variable is passed as the first argument to action_sub
. You have correctly accounted for this in your other type bound procedures, but are missing it in this procedure. You also need to import the derived type in the interface block within action_sub
in order to use the type there. This modified version of just that procedure allows your module to compile properly:
subroutine action_sub ( me, sub )
class ( test ), target :: me
interface mySub
subroutine sub ( me )
import test
class ( test ), target :: me
end subroutine sub
end interface mySub
call sub ( me )
print *, 'x = ', me % x, ', y = ', me % y
end subroutine action_sub
next, in your main program where you do:
call myTest % action ( square_sub )
in order to reference square_sub
here you need to make the procedure public in your module. Once you remove the private
attribute from the module procedure your code compiles and runs:
x = 5.00000000 , y = 10.0000000
x = 5.00000000 , y = 25.0000000
这篇关于如何将子例程名称作为Fortran类中的参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!