如何在 Fortran 中将子程序名称作为参数传递 类
How to pass subroutine names as arguments in Fortran classes
在 中,我们学习了如何在 Fortran 中将子例程名称作为参数传递。我们如何在 class 结构中执行此操作?
随后的代码使用 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
接下来是主程序。它包括一个用作诊断的例程 check
。
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
模块:
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
非常感谢@Vladimir F 提供的原始解决方案和提示。
您的错误是由于程序中缺少参数 action_sub
和其他一些小问题造成的。此过程通过
绑定到您的派生类型
procedure, public :: action => action_sub
默认情况下,多态 class 变量作为第一个参数传递给 action_sub
。您已在其他类型绑定过程中正确考虑了这一点,但在此过程中遗漏了它。您还需要在 action_sub
内的接口块中导入派生类型,以便在那里使用该类型。这个过程的修改版本允许你的模块正确编译:
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
接下来,在您的主程序中您执行的操作:
call myTest % action ( square_sub )
为了在此处引用 square_sub
,您需要在模块中创建过程 public。从模块过程中删除 private
属性后,您的代码将编译并运行:
x = 5.00000000 , y = 10.0000000
x = 5.00000000 , y = 25.0000000
在
随后的代码使用 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
接下来是主程序。它包括一个用作诊断的例程 check
。
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
模块:
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
非常感谢@Vladimir F 提供的原始解决方案和提示。
您的错误是由于程序中缺少参数 action_sub
和其他一些小问题造成的。此过程通过
procedure, public :: action => action_sub
默认情况下,多态 class 变量作为第一个参数传递给 action_sub
。您已在其他类型绑定过程中正确考虑了这一点,但在此过程中遗漏了它。您还需要在 action_sub
内的接口块中导入派生类型,以便在那里使用该类型。这个过程的修改版本允许你的模块正确编译:
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
接下来,在您的主程序中您执行的操作:
call myTest % action ( square_sub )
为了在此处引用 square_sub
,您需要在模块中创建过程 public。从模块过程中删除 private
属性后,您的代码将编译并运行:
x = 5.00000000 , y = 10.0000000
x = 5.00000000 , y = 25.0000000