8

我有一个派生类型 ( wrapper),其中包含另一个派生类型 ( over)。对于后者,赋值运算符已被重载。由于派生类型的分配是按默认组件进行的,我希望分配两个实例会在某些时候wrapper调用重载分配。over但是,使用下面的程序,似乎并非如此。wrapper仅当我还为包含实例之间的显式赋值而重载赋值时才调用重载赋值over(通过取消注释代码行)。为什么?我觉得这有点违反直觉。有什么办法可以避免包装类型的重载?

module test_module
  implicit none

  type :: over
    integer :: ii = 0
  end type over

  type :: wrapper
    type(over) :: myover
  end type wrapper

  interface assignment(=)
    module procedure over_assign
    !module procedure wrapper_assign
  end interface assignment(=)

contains

  subroutine over_assign(other, self)
    type(over), intent(out) :: other
    type(over), intent(in) :: self

    print *, "Assignment of over called"
    other%ii = -1

  end subroutine over_assign

  !subroutine wrapper_assign(other, self)
  !  type(wrapper), intent(out) :: other
  !  type(wrapper), intent(in) :: self
  !
  !  other%myover = self%myover
  !
  !end subroutine wrapper_assign

end module test_module

program test
  use test_module
  implicit none

  type(wrapper) :: w1, w2

  print *, "Assigning wrapper instances:"
  w2 = w1

end program test
4

2 回答 2

10

这种 [不幸的] 情况是语言规则 (F90+) 对派生类型进行内在赋值的结果。详细信息在 F2008 7.2.1p13 中有详细说明。总而言之,派生类型的内在赋值(在 wrapper_assign 特定注释掉的情况下发生的赋值)不会为任何派生类型的组件调用非类型绑定定义的赋值。在 F90/F95 中,如果您想在组件层次结构的某个较低级别定义分配,那么您需要为直到基础对象的所有父组件定义分配。

F2003 为语言添加了类型绑定定义的赋值,这由派生类型的内在赋值调用的。使用它而不是指定定义分配的独立通用形式。(这也避免了类型名称可访问但定义的分配过程不可访问的潜在问题。)

于 2013-09-29T02:58:17.220 回答
1

只是为了完成线程:对我有用的 IanH 建议的具体实现(请赞成他的原始答案而不是这个)是以下一个:

module test_module
  implicit none

  type :: over
    integer :: ii = 0
  contains
    procedure :: over_assign
    generic :: assignment(=) => over_assign
  end type over

  type :: wrapper
    type(over) :: myover
  end type wrapper

contains

  subroutine over_assign(other, self)
    class(over), intent(out) :: other
    class(over), intent(in) :: self

    print *, "Assignment of over called"
    other%ii = -1

  end subroutine over_assign

end module test_module


program test
  use test_module
  implicit none

  type(wrapper) :: w1, w2

  print *, "Assigning wrapper instances:"
  w2 = w1

end program test
于 2013-09-29T20:29:13.190 回答