在我正在进行的项目中,我发现自己经常需要调整对象数组的大小,因为新对象被创建并且旧对象被销毁。在整个代码中,许多不同的派生类型都会发生这种情况,其中大多数彼此没有关系。编写代码为唯一的派生类型调整这些数组的大小是很乏味的,所以我想我会尝试使用无限的多态虚拟参数编写几个帮助子例程,以便任何派生类型数组都可以使用这些子例程。
我发现我的无限多态例程可以编译和调用CLASS(*),INTENT(INOUT) :: val
。此虚拟参数将接受整数、可分配整数或指向整数的指针。但是,一旦我尝试添加ALLOCATABLE
orPOINTER
属性,子例程就会正确编译,但我无法在没有获得编译器错误的情况下调用它。由于我的目标是能够调整派生类型数组的大小,因此这些属性对于例程能够解除分配/分配/关联值是必需的。
这是一些测试代码,它们甚至没有尝试实际做任何事情但无法编译。此版本使用标量具体类型,但在使用具体类型数组或派生类型数组的原始代码中也会出现相同的错误
MODULE Resize_mod
PUBLIC
CONTAINS
SUBROUTINE resize(val)
CLASS(*),INTENT(INOUT) :: val
WRITE(*,*) 'resize'
ENDSUBROUTINE resize
SUBROUTINE resize_alloc(val)
CLASS(*),ALLOCATABLE,INTENT(INOUT) :: val
WRITE(*,*) 'resize_alloc'
ENDSUBROUTINE resize_alloc
SUBROUTINE resize_ptr(val)
CLASS(*),POINTER,INTENT(INOUT) :: val
WRITE(*,*) 'resize_ptr'
ENDSUBROUTINE resize_ptr
ENDMODULE Resize_mod
PROGRAM testResize
USE Resize_mod
INTEGER,TARGET :: array0d
INTEGER,ALLOCATABLE :: alloc0d
INTEGER,POINTER :: ptr0d
array0d=1
CALL resize(array0d)
ALLOCATE(alloc0d)
alloc0d=1
CALL resize(alloc0d)
!Following line gives: "Error: Actual argument to ‘val’ at (1) must be polymorphic"
CALL resize_alloc(alloc0d)
ALLOCATE(ptr0d)
ptr0d=1
CALL resize(ptr0d)
!Following line gives: "Error: Actual argument to ‘val’ at (1) must be polymorphic"
CALL resize_ptr(ptr0d)
ENDPROGRAM testResize
如图所示,代码产生以下错误:
testResize.f90:31:20:
CALL resize_alloc(alloc0d)
1
Error: Actual argument to ‘val’ at (1) must be polymorphic
testResize.f90:37:18:
CALL resize_ptr(ptr0d)
1
Error: Actual argument to ‘val’ at (1) must be polymorphic
如果我注释掉错误中命名的 2 行,我会得到以下正确输出:
resize
resize
resize
我已经广泛编写了 Fortran 代码,但以前从未尝试过使用无限多态性。请让我知道我正在尝试做的事情是否可行,如果可以,我做错了什么。
我正在使用 gfortran 编译器 5.4.0,据我所知,它应该完全支持无限多态性。