是否可以在 Fortran 中创建一个可调用的 class 实例?
Is it possible to make a class instance callable in Fortran?
我有一个多项式 class TPoly
,请参阅下面的代码,它采用系数数组 coefs
并在某个点 x
使用eval
方法。我想知道是否可以通过使实例 p
可调用来直接评估多项式,即使用 p(x)
而不是 p%eval(x)
。在 Python 中,可以通过定义 __call__
方法来实现所需的行为。 Fortran 中是否存在类似的东西?
我想制作另一个 class,它将包含许多 TPoly
属性,并且我想避免组件选择的链接 object%poly1%eval(x)
。指向 class 方法的函数指针可以解决我的问题,但我发现这是不可能的,请参阅 .
module polymod
implicit none
integer, parameter :: rp = kind(1.0d0)
! polynomial class
type :: TPoly
real(rp), allocatable :: coefs(:)
contains
procedure, pass :: eval => eval_poly
end type
contains
real(rp) function eval_poly(self, x)
class(TPoly), intent(in) :: self
real(rp), intent(in) :: x
eval_poly = polynomial(x, self%coefs)
end function eval_poly
! use Horner's method to evaluate polynomial
real(rp) function polynomial(x, coefs)
real(rp), intent(in) :: x, coefs(:)
real(rp) :: p
integer :: n, i
n = size(coefs)
p = coefs(n)
do i = n-1, 1, -1
p = p * x + coefs(i)
end do
polynomial = p
end function polynomial
end module polymod
program main
use polymod
implicit none
type(TPoly) :: p
real(rp) :: coefs(3)
real(rp) :: x = 2.0_rp
coefs = (/3.0_rp, -1.0_rp, 1.0_rp/)
p = TPoly(coefs)
print *, p%eval(x)
! I would like to use
! print *, p(x)
end program main
很遗憾,不,这是不可能的。据我所知,也没有很好的解决方法可以模拟这种行为。
如果可能的话,需要避免与 Fortran 的数组访问语法冲突。考虑以下因素:
program main
use polymod
implicit none
! Declare an array of type TPoly.
type(TPoly) :: p(1)
! Initialise the array.
p = [TPoly(coefs=[3.0_rp, -1.0_rp, 1.0_rp])]
! Try to print.
print *, p(1)
end program
编译器无法区分 p(1)
引用数组的第一个元素 p
与 p(1)
调用 class 函数作为elemental
函数作用于 p
的每个元素,参数为 1
.
您可以区分 non-elemental 函数的两者,但您需要一些像 p(1)(2.0_rp)
这样的语法,而这种语法在 Fortran 的上下文中并不存在。
我有一个多项式 class TPoly
,请参阅下面的代码,它采用系数数组 coefs
并在某个点 x
使用eval
方法。我想知道是否可以通过使实例 p
可调用来直接评估多项式,即使用 p(x)
而不是 p%eval(x)
。在 Python 中,可以通过定义 __call__
方法来实现所需的行为。 Fortran 中是否存在类似的东西?
我想制作另一个 class,它将包含许多 TPoly
属性,并且我想避免组件选择的链接 object%poly1%eval(x)
。指向 class 方法的函数指针可以解决我的问题,但我发现这是不可能的,请参阅
module polymod
implicit none
integer, parameter :: rp = kind(1.0d0)
! polynomial class
type :: TPoly
real(rp), allocatable :: coefs(:)
contains
procedure, pass :: eval => eval_poly
end type
contains
real(rp) function eval_poly(self, x)
class(TPoly), intent(in) :: self
real(rp), intent(in) :: x
eval_poly = polynomial(x, self%coefs)
end function eval_poly
! use Horner's method to evaluate polynomial
real(rp) function polynomial(x, coefs)
real(rp), intent(in) :: x, coefs(:)
real(rp) :: p
integer :: n, i
n = size(coefs)
p = coefs(n)
do i = n-1, 1, -1
p = p * x + coefs(i)
end do
polynomial = p
end function polynomial
end module polymod
program main
use polymod
implicit none
type(TPoly) :: p
real(rp) :: coefs(3)
real(rp) :: x = 2.0_rp
coefs = (/3.0_rp, -1.0_rp, 1.0_rp/)
p = TPoly(coefs)
print *, p%eval(x)
! I would like to use
! print *, p(x)
end program main
很遗憾,不,这是不可能的。据我所知,也没有很好的解决方法可以模拟这种行为。
如果可能的话,需要避免与 Fortran 的数组访问语法冲突。考虑以下因素:
program main
use polymod
implicit none
! Declare an array of type TPoly.
type(TPoly) :: p(1)
! Initialise the array.
p = [TPoly(coefs=[3.0_rp, -1.0_rp, 1.0_rp])]
! Try to print.
print *, p(1)
end program
编译器无法区分 p(1)
引用数组的第一个元素 p
与 p(1)
调用 class 函数作为elemental
函数作用于 p
的每个元素,参数为 1
.
您可以区分 non-elemental 函数的两者,但您需要一些像 p(1)(2.0_rp)
这样的语法,而这种语法在 Fortran 的上下文中并不存在。