Fortran派生类型:重载赋值运算符不使用' PARAMETER'属性

时间:2014-08-25 22:54:41

标签: fortran derived-types

我正在使用派生类型(bicomplex)和赋值运算符(=)的重载,因此可以将real*8分配给bicomplex。 bicplx模块的MWE如下:

MODULE bicplx

  type bicomplex
    COMPLEX*16 :: a
    COMPLEX*16 :: b
  end type

  interface assignment(=)
    module procedure dble_assign_bicplx
  end interface

contains

  subroutine dble_assign_bicplx(qleft, xright) 
    implicit none         
    type(bicomplex), intent(out) :: qleft
    double precision, intent(in) :: xright

    qleft%a = xright
    qleft%b = 0.0d0          
    return
  end subroutine dble_assign_bicplx

end MODULE

真实到复杂的分配由Fortran内在处理。这种方法适用于"典型的" bicomplex变量,但是当我想将real*8分配给具有PARAMETER属性的bicomplex时会中断:

TYPE(bicomplex) :: test1
test1 = 1.d0

完美无缺,但是:

TYPE(bicomplex), parameter :: test1 = 1.d0

无法编译并提供2个错误:Error: Incompatible derived type in PARAMETER at (1)Error: Can't convert REAL(8) to TYPE(bicomplex) at (1)。 然而,

TYPE(bicomplex), parameter :: test1 = bicomplex(1.d0, 0.d0)

完美无缺。

是否存在我遗漏的内容,或者是否是使用重载赋值运算符无法分配参数的标准的一部分?理想情况下,我想使用F90 / F95(而非2003或2008)来解决这个问题。

2 个答案:

答案 0 :(得分:2)

我对标准的阅读是在这里不能使用定义的运算符。我的想法是,这是因为运算符用于已定义的赋值,其中使用了命名常量初始化(参见Fortran 2008的R503和C507,在5.2.1节中)

在Fortran 2008第5.2.3节中,关于初始化:

  

如果初始化为= constant-expr ,则最初使用 constant-expr 指定的值定义变量;如有必要,根据内在分配规则转换价值

该段落中可能存在一些歧义(未显示),因为它首先引用了没有 parameter属性的实体。因此,在5.3.13节中查看parameter属性:

  

实体具有由 constant-expr 指定的值,必要时转换为实体的类型,类型参数和形状。

但是,第5.4.11节(针对parameter声明)可能会强调这种转换是通过内在分配来实现的:

  

每个命名常量的值是由相应的常量表达式指定的值;如有必要,根据内在分配规则转换价值

对于第一个命名的常量情况,没有从内在类型到派生类型的内在赋值。在第二种情况下,使用派生类型的构造函数,确实正在使用内部赋值。

答案 1 :(得分:2)

“参数”是命名常量。语言规则要求命名常量的值可以在“编译时”确定 - 即在程序执行之前。这意味着用于给命名常量赋值的表达式需要能够在编译时确定。最近标准中的语言术语是“常量表达式”,在早期标准中,它也被称为“初始化表达式”(可以在程序执行之前用作初始化程序)。

定义的赋值是一个可执行的操作 - 运行时,程序执行定义的赋值后面的过程中的语句。这通常不能在编译时完成。

正如您所发现的,您可以使用结构构造函数,其中组件初始值设定项是常量表达式,以初始化派生类型命名常量。