是否有办法使=运算符重载,以便您可以编写如下示例中的赋值:
module constants_mod
integer,parameter :: dpn = selected_real_kind(14)
end module
module vectorField_mod
use constants_mod
implicit none
private
public :: vectorField
public :: allocateX,allocateY,allocateZ
public :: delete
! public :: operator(=)
type vectorField
integer,dimension(3) :: sx,sy,sz
real(dpn),dimension(:,:,:),allocatable :: x,y,z
end type
interface delete
module procedure deallocateVectorField
end interface
! interface operator (=)
! module procedure vectorAssign
! end interface
contains
! function vectorAssign(f) result(q)
! implicit none
! real(dpn),intent(in) :: f
! type(vectorField) :: q
! q%x = f; q%y = f; q%z = f
! end function
! subroutine vectorAssign(f,g)
! implicit none
! type(vectorField),intent(inout) :: f
! real(dpn),intent(in) :: g
! f%x = g; f%y = g; f%z = g
! end subroutine
subroutine allocateX(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%x)) deallocate(field%x)
allocate(field%x(Nx,Ny,Nz))
field%sx = shape(field%x)
end subroutine
subroutine allocateY(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%y)) deallocate(field%y)
allocate(field%y(Nx,Ny,Nz))
field%sy = shape(field%y)
end subroutine
subroutine allocateZ(field,Nx,Ny,Nz)
implicit none
type(vectorField),intent(inout) :: field
integer,intent(in) :: Nx,Ny,Nz
if (allocated(field%z)) deallocate(field%z)
allocate(field%z(Nx,Ny,Nz))
field%sz = shape(field%z)
end subroutine
subroutine deallocateVectorField(field)
implicit none
type(vectorField),intent(inout) :: field
deallocate(field%x,field%y,field%z)
field%sx = 0; field%sy = 0; field%sz = 0
end subroutine
end module
program test
use constants_mod
use vectorField_mod
implicit none
type(vectorField) :: a
integer :: N = 1
real(dpn) :: dt = 0.1
call allocateX(a,N,N,N)
call allocateY(a,N,N,N)
call allocateZ(a,N,N,N)
a%x = dble(1.0) ! want to avoid this
a%y = dble(1.0) ! want to avoid this
a%z = dble(1.0) ! want to avoid this
a = real(1.0,dpn) ! want this instead (does not compile)
call delete(a)
end program我尝试过两种不同的方法(如注释中所示),但我看到错误,指出泛型规范中存在语法错误(用于发布=操作符)。
发布于 2015-01-27 16:25:17
定义的赋值operator(=)不正确,但assignment(=)是:参见Fortran 200812.4.3.4.3。所以你想要这两个块
public :: assignment (=)和
interface assignment (=)
module procedure vectorAssign
end interface请注意,定义赋值的正确方法是使用子程序(虽然受让人可以使用intent(out)而不是intent(inout))。
发布于 2015-01-27 16:34:02
=不是一个运算符,它是Fortran中的一个任务,它们是非常不同的野兽。
对于在Fortran 90中发现并在其他答案中解释得很好的经典可能性,Fortran 2003增加了将重载运算符和赋值与派生类型绑定的更好的可能性。
这样,您肯定不会在没有赋值的情况下导入类型(在本例中,请注意公共和私有语句!)它可能会产生非常不愉快的后果,并且很难调试:
type vectorField
integer,dimension(3) :: sx,sy,sz
real(dpn),dimension(:,:,:),allocatable :: x,y,z
contains
procedure :: assignVector
generic :: assignment(=) => assignVector
end type这样你就不必那么小心地不忘记public :: assignment (=)了
发布于 2015-01-27 16:26:49
是的,您可以使赋值操作符超载。赋值操作符的语法和要求与其他运算符不同,因为语义根本不同:所有其他运算符都根据一个或两个参数计算一个新值,而不更改参数,而赋值则更改左边参数的值。
在你的例子中,我认为应该是这样的:
module vectorField_mod
! ...
interface assignment (=)
module procedure vectorAssign
end interface
contains
! ...
subroutine vectorAssign(f,g)
implicit none
type(vectorField),intent(out) :: f
real(kind = dpn), intent(in) :: g
f%x = g
f%y = g
f%z = g
end subroutine vectorAssign
end module vectorField_modhttps://stackoverflow.com/questions/28174711
复制相似问题