我正在尝试为自定义类型重载赋值运算符,并希望它能够使用自动分配。我阅读了这个线程,并编写了以下代码:
module overload_op
implicit none
PUBLIC ASSIGNMENT(=)
TYPE, PUBLIC :: my_type
real :: real_member
END TYPE my_type
INTERFACE ASSIGNMENT (=)
MODULE PROCEDURE assign_my_type_my_type_elem
MODULE PROCEDURE assign_my_type_my_type
END INTERFACE
contains
ELEMENTAL SUBROUTINE assign_my_type_my_type_elem (var1, var2)
TYPE(my_type), INTENT(OUT) :: var1
TYPE(my_type), INTENT(IN) :: var2
var1%real_member = var2%real_member
END SUBROUTINE assign_my_type_my_type_elem
SUBROUTINE assign_my_type_my_type (var1, var2)
TYPE(my_type), ALLOCATABLE, INTENT(OUT) :: var1(:)
TYPE(my_type), ALLOCATABLE, INTENT(IN) :: var2(:)
if (.not.allocated(var1)) allocate(var1(size(var2)))
! Call the elemental assignment subroutine for gfortran, fail for Intel
var1(:) = var2(:)
END SUBROUTINE assign_my_type_my_type
end module overload_op
program main
use overload_op
implicit none
TYPE(my_type) :: a(3), b(3)
TYPE(my_type), allocatable :: c(:), d(:)
b = a
allocate(d(3))
c = d
end program main
在我的理解中,对于可分配数组,代码应该调用assign_my_type_my_type
,对于定义形状的数组(例如使用(:)规范的数组)或简单的my_type
变量,应调用elemental。
这在我使用gfortran编译器最新版本10.0.1时能够按照我的意愿工作。但是当我尝试使用ifort编译器(intel/2020.1版本)进行编译时,首先会出现以下错误:
error #6437:一个子例程或函数正在递归地调用自身。 [ASSIGN_MY_TYPE_MY_TYPE] var1(:) = var2(:)
当我将代码更改为
call assign_my_type_my_type_elem(var1(:), var2(:))
我在主程序的变量a,b上遇到了没有可分配属性的错误。
一个可分配的虚参只能是与可分配的实参相关联的参数。
所以我的问题是:我的实现是否完全错误,并且使用(:)符号时,我没有调用基本赋值运算符?换句话说,gfortran有bug并且Intel是对的,还是反过来?
assign_my_type_my_type
,而对于定义形状的数组,则应该调用elemental函数。您能解释一下为什么这样做吗? - francescalusassign_my_type_my_type
都不能直接通过定义的赋值调用:它的第二个参数是可分配的。 - francescalus