如何在抽象接口块中为延迟绑定指定函数接口作为类型绑定过程?
How are function interfaces specified in abstract interface blocks for deferred binding as a type bound procedure?
我想声明一个抽象类型 abstract_tensor
并指定每个扩展 abstract_tensor
的类型都必须实现的一些过程(包括它们的接口)。
举个例子,假设我希望扩展 abstract_tensor
的每个类型都有一个类型绑定过程 sph
,return 是具体类型的一个实例,并且是一个 函数,不是子程序。
这是该情况的非编译实现:
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
并且类型绑定过程 tr
和 sph
计算了它的迹线和流体静力学部分。 tr
的return类型应该是real
,sph
的return类型应该是另一个sym_tensor
.
如何在 abstract interface
块中定义 sph_interface
的 return 类型,以便编译并强制每个扩展抽象类型的类型实现这样的功能?
在 Fortran 中,所有抽象多态变量 must be 之一:
- 虚拟变量
- 指针
- 可分配
你的抽象函数
function sph_interface(self)
import :: abstract_tensor
class(abstract_tensor), intent(in) :: self
class(abstract_tensor) :: sph_interface
end function sph_interface
return是class(abstract_tensor)
的一个变量,是一个抽象的多态变量,不是上面的一个。
最简单的更改是使 return 类型 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 标准的限制或编译器的限制,我不确定是否需要源分配。
我想声明一个抽象类型 abstract_tensor
并指定每个扩展 abstract_tensor
的类型都必须实现的一些过程(包括它们的接口)。
举个例子,假设我希望扩展 abstract_tensor
的每个类型都有一个类型绑定过程 sph
,return 是具体类型的一个实例,并且是一个 函数,不是子程序。
这是该情况的非编译实现:
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
并且类型绑定过程 tr
和 sph
计算了它的迹线和流体静力学部分。 tr
的return类型应该是real
,sph
的return类型应该是另一个sym_tensor
.
如何在 abstract interface
块中定义 sph_interface
的 return 类型,以便编译并强制每个扩展抽象类型的类型实现这样的功能?
在 Fortran 中,所有抽象多态变量 must be 之一:
- 虚拟变量
- 指针
- 可分配
你的抽象函数
function sph_interface(self)
import :: abstract_tensor
class(abstract_tensor), intent(in) :: self
class(abstract_tensor) :: sph_interface
end function sph_interface
return是class(abstract_tensor)
的一个变量,是一个抽象的多态变量,不是上面的一个。
最简单的更改是使 return 类型 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 标准的限制或编译器的限制,我不确定是否需要源分配。