【问题标题】:Compare two derived type variables using gfortran (gcc8)使用 gfortran (gcc8) 比较两个派生类型变量
【发布时间】:2020-01-10 18:42:42
【问题描述】:

我有以下派生类型:

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 bits 下使用 gfortran (gcc8)

【问题讨论】:

    标签: fortran gfortran fortran90


    【解决方案1】:

    说到操作,比如这里需要的比较操作,有两种不同的类型:内在操作和定义操作。

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

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

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

    之类的消息

    错误 #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)) 以允许将其用作类型绑定过程。使用独立功能,这不是必需的。

    最后,这个讨论的大部分内容适用于更一般的(二进制)操作,而不仅仅是那些重载内在操作的操作。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 感谢分享有关重载的信息,我会试一试。作为一种解决方法,我编写了返回 .true 的函数。或.false。检查两种日期时间派生类型的各个变量-正如您在答案中建议的那样-。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多