使用重载运算符打包

时间:2019-04-10 13:09:42

标签: fortran

我正在尝试在自定义类型数组上使用pack函数。我已经设置了一个小模块,其类型和接口可以重载.eq.。如果我做一个简单的比较,重载的运算符似乎可以工作,但是当在pack函数的上下文中使用时,会出现错误。

!The module

module m_types

  type :: t_property
     character(12) :: key
     logical :: value
  end type t_property

  type(t_property), allocatable, dimension(:) :: properties

  public :: operator(.eq.)
  interface operator(.eq.)
     procedure prop_eq
  end interface operator(.eq.)

contains

  pure function prop_eq(first, second) result(res)
    type(t_property), intent(in) :: first, second
    logical :: res

    if (first%key .eq. second%key) then
       res = .true.
    else
       res = .false.
    end if

  end function prop_eq

end module m_types

! The test program
program textadventure
  use m_types
  implicit none
  type(t_property) :: temp

    allocate(properties(0))

    temp = t_property(key="lit", value=.true.)
    properties = [properties, temp]

    temp = t_property(key="visited", value=.false.)
    properties = [properties, temp]

    temp = t_property(key="lit", value=.false.)
    properties = [properties, temp]

    temp = t_property(key="cold", value=.false.)
    properties = [properties, temp]

    temp = t_property(key="cold", value=.false.)
    properties = [properties, temp]

    print *, properties
    print *,  (properties(4) .eq. temp) ! Succeeds

    print *, size(pack(properties, properties .eq. temp)) ! Fails

    deallocate(properties)

end program textadventure

GCC错误消息

Error: Operands of comparison operator ‘.eq.’ at (1) are TYPE(t_property)/TYPE(t_property)

规范说PACK中的掩码应该是我认为我提供的逻辑标量-有人可以指出我错了吗?

2 个答案:

答案 0 :(得分:2)

在比较掩码时,properties .eq. temp有两个对象type(t_property),并且希望使用函数prop_eq提供该已定义的操作。

但是,第一个操作数properties是一个数组,prop_eq的第一个伪参数是一个标量。结果,没有定义的运算符.eq.可用。您应该提供一个函数来处理数组的第一个参数。一种方法是使prop_eq成为元素。

.eq.返回数组结果是适当的:mask=的{​​{1}}参数应与array参数一致(并且您不希望它是标量的)。

在成功比较PACK中,第一个操作数是标量。

答案 1 :(得分:2)

针对感兴趣者的更正代码,现在可以按预期打包。

module m_types

  type :: t_property
     character(12) :: key
     logical :: value
  end type t_property

  type(t_property), allocatable, dimension(:) :: properties

  public :: operator(.eq.)
  interface operator(.eq.)
     procedure prop_eq
  end interface operator(.eq.)

contains

  function prop_eq(first, second) result(res)
    type(t_property), intent(in) :: second
    type(t_property), intent(in), dimension(:) :: first
    logical, dimension(:), allocatable :: res
    integer :: i

    allocate(res(0))
    do i=1, size(first)
       if (first(i)%key .eq. second%key) then
          res = [res, .true.]
       else
          res = [res, .false.]
       end if
    end do

  end function prop_eq

end module m_types

program textadventure
  use m_types
  implicit none
  type(t_property) :: temp

    allocate(properties(0))

    temp = t_property(key="cold", value=.false.)
    properties = [properties, temp]

    temp = t_property(key="lit", value=.true.)
    properties = [properties, temp]

    temp = t_property(key="visited", value=.false.)
    properties = [properties, temp]

    temp = t_property(key="lit", value=.false.)
    properties = [properties, temp]

    temp = t_property(key="cold", value=.false.)
    properties = [properties, temp]

    temp = t_property(key="cold", value=.false.)
    properties = [properties, temp]

    print *, size(properties)
    print *,
    print *, pack(properties, mask = properties .eq. temp)

    deallocate(properties)

end program textadventure