定义特定于派生类型的赋值/运算符过程时出现错误 #6259、#7715、#6355、#6303

Errors #6259, #7715, #6355, #6303 in defining Derived Type specific assignment/operator procedures

提问人:mEm 提问时间:11/21/2022 最后编辑:mEm 更新时间:11/21/2022 访问量:76

问:

首先,大家好!祝大家有一个良好的开始一周:)

在增强(以及简化一些语法)以前开发的派生类型时,我(还有一些仍然)遇到了一些错误,如标题规范(注意:有关完整消息及其原因的详细信息,请阅读以下代码中的注释行:))。

其中,我最不明白的(我为什么要得到它们)是 和 .error #6355: This binary operation is invalid for this data type.operator(==)error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.assignment(=)

下面是一个源代码示例(注意:为了重现这些错误,请注释掉类型绑定过程部分,并取消注释掉两个接口正文):

module MPolicyMod
   implicit none
   private
   public :: MPolicy

   type, public :: MPolicy_t
      real(kind = 8) :: delta_fI_fct_
      real(kind = 8) :: delta_fJ_fct_
      real(kind = 8) :: interp_I_fct_
      real(kind = 8) :: interp_J_fct_
      integer :: id_pol_
   contains
      generic :: assignment(=) => MPolicy_fromPol_sub, MPolicy_fromID_sub
      procedure, private, pass :: MPolicy_fromID_sub, MPolicy_fromPol_sub
      generic :: operator(==) => MPolicy_isID
      procedure, pass, private :: MPolicy_isID
   end type MPolicy_t

   integer, public, parameter :: MPolicy_NULL  = 0
   integer, public, parameter :: MPolicy_DEF   = 1
   integer, public, parameter :: MPolicy_CONST = 2


   interface MPolicy_t
      module procedure MPolicy_constructor_integer
      module procedure MPolicy_constructor_real
      module procedure MPolicy_fromID
   end interface

   ! interface assignment(=)
   !   module procedure MPolicy_fromPol_sub
   !   module procedure MPolicy_fromID_sub
   ! end interface assignment(=)

   ! interface operator(==)
   !   module procedure MPolicy_isID
   ! end interface operator(==)


contains

   !> Main default constructor.
   function MPolicy_constructor_real(dfi, dfj, interpi, interpj, id) result(pol)
      real(kind = 8), intent(in) :: dfi, dfj, interpi, interpj
      integer, intent(in) :: id
      type(MPolicy_t) :: pol

      print *, ' Default constructor (as compiler)...'

      pol%delta_fI_fct_ = dfi
      pol%delta_fJ_fct_ = dfj
      pol%interp_I_fct_ = interpi
      pol%interp_J_fct_ = interpj
      pol%id_pol_       = id
   end function MPolicy_constructor_real


   function MPolicy_constructor_integer(dfi, dfj, interpi, interpj, id) result(pol)
      integer, intent(in) :: dfi, dfj, interpi, interpj, id
      type(MPolicy_t) :: pol

      print *, ' Default constructor (integer version)...'

      pol = MPolicy_t(real(dfi, 8), &
                        real(dfj, 8), &
                        real(interpi, 8), &
                        real(interpj, 8), id)
   end function


   function MPolicy_fromID(id) result(pol)
      integer, intent(in) :: id
      type(MPolicy_t)     :: pol

      print *, ' Constructor from ID...'

      select case (id)
         case (MPolicy_NULL)
            return
         case (MPolicy_DEF)
            pol = MPolicy_t(2, 2, 2, 2, MPolicy_DEF)
         case (MPolicy_CONST)
            pol = MPolicy_t(1, 1, 1, 1, MPolicy_CONST)
         case default
            block
               character(len=3) :: fmt

               write(fmt, '(i)'), id
               stop ' [ERROR] Unknow policy identifier "id"= '//fmt
            end block
      end select
   end function MPolicy_fromID


   subroutine MPolicy_fromPol_sub(lhs, rhs)
      class(MPolicy_t), intent(in) :: rhs
      class(MPolicy_t), intent(out) :: lhs

      lhs%delta_fI_fct_ = rhs%delta_fI_fct_
      lhs%delta_fJ_fct_ = rhs%delta_fJ_fct_
      lhs%interp_I_fct_ = rhs%interp_I_fct_
      lhs%interp_J_fct_ = rhs%interp_J_fct_
      lhs%id_pol_       = rhs%id_pol_
   end subroutine MPolicy_fromPol_sub


   subroutine MPolicy_fromID_sub(lhs, rhs)
      class(MPolicy_t), intent(out) :: lhs
      integer, intent(in)           :: rhs

      lhs = MPolicy_t(rhs)
   end subroutine MPolicy_fromID_sub


   function MPolicy(mpol) result(pol)
      integer :: mpol
      type(MPolicy_t) :: pol

      pol = MPolicy_t(mpol)
   end function MPolicy


   pure function MPolicy_isID(pol, id) result(isID)
      class(MPolicy_t), intent(in) :: pol
      integer, intent(in) :: id
      logical :: isID

      isID = pol%id_pol_ == id
   end function MPolicy_isID

end module

示例程序:

program test

   use MPolicyMod
   implicit none


   ! ! NOTE: generates
   ! !       error #6259: This array or function or substring is invalid in constant expressions.   [MPOLICYMOD^MPOLICY_FROMID]
   ! !       error #7715: Replacing invalid structure constructor by integer 1.   [<NULL_STRING>]
   ! type(MPolicy_t) :: pol = MPolicy_t(MPolicy_NULL)


   type(MPolicy_t) :: pol

   ! =========================================================================
   print *, pol
   pol = MPolicy_t(MPolicy_NULL)
   print *, pol

   ! ! NOTE: generates (without TYPE-BOUND specification)
   ! !       error #6355: This binary operation is invalid for this data type.
   print *, pol == MPolicy_NULL

   pol = MPolicy_t(1, 1, 1, 1, 2)
   print *, pol

   ! ! NOTE: generates (without TYPE-BOUND specification)
   ! !       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.
   pol = MPolicy_DEF
   print *, pol
end program test

然后,在通读了 ISO Fortran 标准 2003 草案文档后,在第 4.5.4 节“类型绑定过程”中,规则 R452 指出,我们可以在 proc-binding-stmt 的泛型绑定类型中指定为泛型规范在那里,我意识到我缺少这些操作员/分配程序的类型绑定规范assignment(=)

那么,为什么只有接口主体不足以使其工作呢?

在此之后,我还想知道为什么初始化语句会生成错误 #6259 和 #7715。type(MPolicy_t) :: pol = MPolicy_t(MPolicy_NULL)

为此,我仍然没有自己搜索。但是,如果你在我找到(希望)一个解释之前就带着一个安慰来,那么与你们所有人进行建设性和礼貌的讨论总是好的。

我现在回到我的搜索。祝你有美好的一天:)

fortran 分配运算符 intel-fortran 派生类型

评论

0赞 francescalus 11/21/2022
不能使用函数实现。assignment(=)
0赞 mEm 11/21/2022
@francescalus 事实上,它们不是函数;)
0赞 mEm 11/21/2022
@francescalus等等,你的意思是 ?type(MPolicy_t) :: pol = MPolicy_t(MPolicy_NULL)
2赞 francescalus 11/21/2022
是的,对不起,这是真的。但也许表明你的例子可以简化一点(参见最小的可重现的例子),因为有很多事情乍一看是令人困惑的。(任何真正回答这个问题的人都会花比我更多的时间瞥一眼,但如果可能的话,让他们的生活更轻松一点也无妨。
1赞 francescalus 11/21/2022
不用担心:初始化仅使用内部赋值,从不定义赋值。实际上,请担心它,因为我看到你也问过这个问题。是的:这是不允许的,但出于完全不同的原因(不是恒定表达式)不允许。type(MPolicy_t) :: pol = MPolicy_t(MPolicy_NULL)

答: 暂无答案