我在子例程中有两个派生类型多态数组(obj1 和 obj2)。基于子程序的使用,虽然两个数组的类型可能不同,但两个数组是相同的类型;例如,A 型或 B 型。在下面的示例代码中,我只展示了抽象类(模型)的一个子类型,而实际上,我希望它适用于多个子类型。此外,在生产代码中,model1 的元素在此副本之前已被修改。
program test
use env_kindtypes, only: si, dp
use abs_obj_model, only: model
use obj_linearDivisionModel, only: linearDivisionModel
implicit none
class(model),allocatable :: model1(:), model2(:)
allocate(linearDivisionModel::model1(10))
!want e.g. model2 = model1([1,4,6,2])
![...]
给定 obj1、obj2(类型 A)(在示例代码中给出的 model1、model2 类型为 linearDivisionMode)和一组索引,我想将指定的元素从 obj1 转移到 obj2,在此过程中分配 obj2。
我已经尝试了很多方法来做到这一点,但似乎都没有奏效。
首先,我尝试使用向量下标直接赋值;这失败了,抱怨不支持直接分配可分配多态数组。
indices = [ 1 , 2 ]
model2 = model1(indices)
结果:
model2 = model1(indices)
1
Error: Assignment to an allocatable polymorphic variable at (1) is not yet supported
其次,我尝试使用源分配。如果我用数组切片表示法尝试这个,它可以工作(但我的问题不能仅仅用这样的范围来表达)。如果我尝试对源数组进行矢量索引,它会编译,但在运行时我会因内存不足而出错(考虑到系统,这不现实)。
allocate(model2,source=model1(indices))
运行时结果:
Operating system error: Cannot allocate memory
Memory allocation failed
Error termination. Backtrace:
#0 0x434471 in __obj_lineardivisionmodel_MOD___copy_obj_lineardivisionmodel_Lineardivisionmode
at build/processed_src/obj_linear_model.f90:462
#1 0x436c75 in cg_charge_fit
at build/processed_src/test.f90:37
#2 0x403019 in main
at build/processed_src/test.f90:22
有效,但不足以满足我的目的。
allocate(model2,source=model1(1:2))
第三,我已经能够分配多态数组以希望手动传输子元素:但是,当我尝试这样做时,我收到了多态对象和内在赋值的抱怨,我将在本文后面讨论。
indices = [ 1 , 2 ]
allocate(model2(size(indices)),source=model1(1))
do i=1,size(indices)
model2(i) = model1(indices(i))
enddo
Error: Nonallocatable variable must not be polymorphic in intrinsic assignment at (1) - check that there is a matching specific subroutine for '=' operator.
我尝试使用类型选择语句来删除多态上下文,但错误仍然存在。
select type (POBJECT => model1)
TYPE IS (linearDivisionModel)
allocate(linearDivisionModel::model2(size(indices)))
do i=1,size(indices)
model2(i) = POBJECT(indices(i))
enddo
end select
结果:
model2(i) = model1(indices(i))
1
Error: Nonallocatable variable must not be polymorphic in intrinsic assignment at (1) - check that there is a matching specific subroutine for '=' operator
作为一种解决方法,我希望使用一个中间指针对象,并从中获取分配。由于 f2008 标准(此处强制执行),我无法将指针分配给向量索引数组。有趣的是,如果我创建一个指针,向量索引该指针,编译器会出现段错误,这表明发生了一些奇怪的事情。
为了解决编译器对内在赋值的抱怨,我考虑过编写赋值例程;然而,这引起了一系列新的担忧:这两个例程继承自的父类型都是抽象的,我似乎无法在该类中指定通用延迟赋值运算符,导致复杂的父类需要相当多的私有方法复制,因为它没有指定私有变量。此外,子类 A 和 B 之间的转换定义不明确。这似乎仍然是唯一剩下的出路,而且看起来很复杂。
如何有效地传输指定的多态子数组?
我正在使用 gfortran 6.1.1 版。