【问题标题】:Is it possible to make a class instance callable in Fortran?是否可以在 Fortran 中使类实例可调用?
【发布时间】:2020-12-13 06:10:49
【问题描述】:

我有一个多项式类TPoly,请参见下面的代码,它采用系数数组coefs 并使用eval 方法在某个点x 评估多项式。我想知道是否可以通过使实例p 可调用来直接评估多项式,即使用p(x) 而不是p%eval(x)。在 Python 中,可以通过定义 __call__ 方法来实现所需的行为。 Fortran 中是否存在类似的东西?

我想创建另一个包含许多TPoly 属性的类,并且我想避免链接组件选择object%poly1%eval(x)。指向类方法的函数指针可以解决我的问题,但我发现这是不可能的,请参阅another thread

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

【问题讨论】:

    标签: class oop fortran callable


    【解决方案1】:

    很遗憾,不,这是不可能的。据我所知,也没有很好的解决方法可以模拟这种行为。

    如果可能,它需要避免与 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) 引用数组的第一个元素 pp(1) 调用类函数作为 elemental 函数作用于 p 的每个元素带有参数1

    对于非元素函数,您可以将两者区分开来,但您需要一些语法,例如 p(1)(2.0_rp),而这种语法在 Fortran 的上下文中不存在。

    【讨论】:

    • 存在类似x(..)(..) 的语法,这意味着在 Fortran 中至少有两种不同的东西。
    • @francescalus 等一下,真的吗?能给我举个例子吗?如果是这样,我会很乐意修改我的答案...
    • @francescalus 啊,是的,你是对的:Fortran 2018 标准草案,第 130 页:B(1)(1:5) 指的是“数组元素作为父字符串”。我会修改我的答案,谢谢。
    • 数组元素子字符串;带类型参数的结构构造函数。
    • @veryreverie 太糟糕了,这会很方便。感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 2022-08-10
    • 1970-01-01
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多