如何在抽象接口块中为延迟绑定指定函数接口作为类型绑定过程?



我想声明一个抽象类型abstract_tensor,并指定一些过程(包括它们的接口),每个扩展abstract_tensor的类型都必须实现。

作为一个例子,假设我希望每个扩展abstract_tensor的类型都有一个类型绑定过程sph,该过程返回具体类型的实例,并且是函数,而不是子例程。

下面是这种情况的非编译实现:

module tensors
implicit none
private
public :: sym_tensor
type, abstract :: abstract_tensor
contains
procedure(tr_interface), deferred :: tr
procedure(sph_interface), deferred :: sph
end type abstract_tensor
abstract interface
!! intrinsic return type works
function tr_interface(self)
import :: abstract_tensor
class(abstract_tensor), intent(in) :: self
real :: tr_interface
end function tr_interface
!! abstract return type not - how do I define the return type correctly here?
function sph_interface(self)
import :: abstract_tensor
class(abstract_tensor), intent(in) :: self
class(abstract_tensor) :: sph_interface
end function sph_interface
end interface
type, extends(abstract_tensor) :: sym_tensor
real :: xx = 0.0
real :: yy = 0.0
real :: zz = 0.0
real :: xy = 0.0
real :: yz = 0.0
real :: xz = 0.0
contains
procedure :: tr => trace
procedure :: sph => spherical_part
end type sym_tensor
contains
real function trace(self)
class(sym_tensor), intent(in) :: self
trace = self%xx + self%yy + self%zz
end function trace
type(sym_tensor) function spherical_part(self)
class(sym_tensor), intent(in) :: self
real :: tr
tr = 1.0/3.0*self%tr()
spherical_part = sym_tensor(tr, tr, tr, 0.0, 0.0, 0.0)
end function spherical_part
end module tensors
program main
use tensors, only: sym_tensor
implicit none
type(sym_tensor) :: t
end program main

这里,sym_tensor扩展了abstract_tensor,类型绑定过程trsph计算了它的迹线和静水部分。tr的返回类型应为real,sph的返回类型应为另一个sym_tensor

我如何在abstract interface块中定义sph_interface的返回类型,以便编译并强制每个类型扩展抽象类型来实现这样的函数?

在Fortran中,所有抽象多态变量必须是:

<<ul>
  • 虚拟变量/gh><<li>指针/gh>
  • 可分配
  • 你的抽象函数

    function sph_interface(self)
    import :: abstract_tensor
    class(abstract_tensor), intent(in) :: self
    class(abstract_tensor) :: sph_interface
    end function sph_interface
    

    返回class(abstract_tensor)的一个变量,它是一个抽象的多态变量,但不是上面的一个。

    最简单的更改是使返回类型为allocatable:
    function sph_interface(self)
    import :: abstract_tensor
    class(abstract_tensor), intent(in) :: self
    class(abstract_tensor), allocatable :: sph_interface
    end function sph_interface
    

    然后sym_tensor实现需要有一个匹配的签名:

    function spherical_part(self)
    class(sym_tensor), intent(in) :: self
    class(abstract_tensor), allocatable :: spherical_part
    real :: tr
    tr = 1.0/3.0*self%tr()
    spherical_part = sym_tensor(tr, tr, tr, 0.0, 0.0, 0.0)
    end function spherical_part
    

    可以编译,但是可能会导致段错误,因为编译器不喜欢多态赋值

    spherical_part = sym_tensor(tr, tr, tr, 0.0, 0.0, 0.0)
    

    您可以通过将简单赋值替换为来源分配来解决这个问题,

    allocate(spherical_part, source=sym_tensor(tr, tr, tr, 0.0, 0.0, 0.0))
    

    我不确定是否由于Fortran标准的限制或编译器的限制而需要源分配。

    最新更新