使用gfortran(gcc8)比较两个派生类型变量

时间:2019-09-08 23:51:19

标签: fortran gfortran fortran90

我具有以下派生类型:

type datetime
    integer     :: year
    integer     :: month
    integer     :: day
    integer     :: hour
    integer     :: minute
end type

我用这种类型定义了两个变量:

type(datetime)                          :: session_end
type(datetime)                          :: session_cursor

我正在尝试比较两个变量,以查看派生类型元素是否具有相同的值。

do while (session_cursor /= session_end)
    ...
end do

但是我得到了

do while (session_cursor /= session_end)
         1
Error: Operands of comparison operator '/=' at (1) are TYPE(datetime)/TYPE(datetime)

我正在FreeBSD 12 64位下使用gfortran(gcc8)

2 个答案:

答案 0 :(得分:1)

我使用gfortran进行了检查,并得到了同样的错误消息。如果比较datetime的各个变量,该代码将起作用。 可能必须使用重载,因为未为您的类型定义比较。查看此示例,了解如何发现https://courses.physics.illinois.edu/phys466/sp2013/comp_info/overload.html

超载

答案 1 :(得分:1)

对于操作(例如此处所需的比较操作),有两种不同的类型:固有操作和 defined 操作。

内部操作是编译器“默认情况下知道的”操作,而定义的操作是由正在编译/使用的代码提供的操作。

仅对内部类型提供内部比较操作。对于内在一元运算符(例如一元减-),操作数必须是内在类型;对于内在二进制运算符,两个操作数都必须是内在类型。

即使对于相等和不相等,也必须将定义的操作用于派生类型。问题的错误消息是说编译器不知道/无法访问这种定义的操作。其他编译器可能会给出诸如

的消息
  

错误#6355:此二进制操作对此数据类型无效。

  

.NE的运算符。运算符是派生类型

  

1511-026(S)比较操作不允许使用操作数类型。

由于没有可用的已定义操作,编译器不得不将派生类型视为固有操作的操作数-不允许。

要提供定义的操作,我们首先提供一个函数。对于此函数来说,返回真/假值是有意义的,它采用此派生类型的两个操作数,而不修改它们:

logical function datetime_unequal(lhs, rhs)
   class(datetime), intent(in) :: lhs, rhs
   datetime_unequal = ...   ! Implement inequality test
end function datetime_unequal

我们可以以明显的方式使用此功能(而不是作为运算符):

do while (datetime_unequal(session_cursor, session_end)))
...
end do

这可能满足许多​​目的,但是我们可以继续进行定义的比较操作的方法。 (为了保持一致性,我们将调用操作符/=。)我们通过提供通用接口或通用绑定重载operator(/=)来实现这一点。

考虑

module datetime_mod
  implicit none

  type datetime
    ...
  contains
    procedure datetime_unequal
    ! A generic binding
    generic :: operator(/=) => datetime_unequal
  end type

! A generic interface
  interface operator(/=)
    module procedure datetime_unequal 
  end interface

contains

  logical function datetime_unequal(lhs, rhs)
    class(datetime), intent(in) :: lhs, rhs
    datetime_unequal = ...   ! Implement inequality test
  end function datetime_unequal

end module datetime_mod

请注意,您无需同时提供通用接口和通用绑定。实际上,在大多数情况下,泛型绑定(在类型定义内部定义)是可取的:只要可以访问类型定义本身,就可以访问;通用接口具有独立的可访问性。

还要注意,比较函数的参数是多态的(class(datetime)),以允许将其用作类型绑定过程。使用独立功能,则不必这样做。

最后,大部分讨论都适用于更一般的(二进制)操作,而不仅仅是那些重载固有操作的操作。