Упаковать используя перегруженный оператор - PullRequest
2 голосов
/ 10 апреля 2019

Я пытаюсь использовать функцию pack для массива пользовательских типов.Я настроил небольшой модуль с типом и интерфейсом для перегрузки .eq..Если я делаю простое сравнение, перегруженный оператор, кажется, работает, однако при использовании в контексте функции пакета я получаю сообщение об ошибке.

!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 ]

2 голосов
/ 10 апреля 2019

Исправленный код для тех, кто заинтересован, теперь он упаковывается как положено.

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
2 голосов
/ 10 апреля 2019

В сравнении для маски properties .eq. temp у вас есть два объекта type(t_property), и вы надеетесь использовать функцию prop_eq для обеспечения этой определенной операции.

Однако первый операнд properties является массивом, а первый фиктивный аргумент prop_eq является скаляром. В результате не существует определенного оператора .eq.. Вы должны предоставить функцию для обработки массива первым аргументом. Одним из способов было бы сделать prop_eq элементным.

Уместно возвращать результат массива из .eq.: аргумент mask= для PACK должен соответствовать аргументу массива (и вы не хотите, чтобы он был скалярным).

В успешном сравнении properties(4) .eq. temp первый операнд является скалярным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...