【问题标题】:Fortran Class (*) in Function Result函数结果中的 Fortran 类 (*)
【发布时间】:2015-01-13 03:05:33
【问题描述】:

我遇到了这篇文章中详述的函数的错误。

出现问题是因为我试图返回与 输入类型。任何人都可以提出解决方案吗?我最初对每个都有一个功能 类型,然后是通用接口将它们分组为相同的名称。现在我正在尝试 使用多态性将所有内容放在一个函数中。

这是 gfortran 给我的错误。

gfortran -o build/lib/foul.o -c -ffree-form -g -J./build/lib lib/foul.f
lib/foul.f:471.45:

Function cassign (expr, a, b, wrn) Result (c)

我尝试使用可分配数组。然后在主程序中做

Character (len=65), Allocatable :: sc(:)
Integer, Allocatable :: ic(:)
Real, Allocatable :: rc(:)

Allocate (sc(1))
Allocate (ic(1))
Allocate (rc(1))

sc = cassign (ra < rb, sa, sb)
ic = cassign (ra < rb, ia, ib)
rc = cassign (ra < rb, ra, rb)

这会返回以下错误

gfortran -o build/utests/test_foul.o -c -ffree-form -g -J./build/lib utests/test_foul.f utests/test_foul.f:315.7:

sc = cassign (ra < rb, sa, sb)
     1
Error: Can't convert CLASS(*) to CHARACTER(1) at (1)
utests/test_foul.f:316.7:

ic = cassign (ra < rb, ia, ib)
     1
Error: Can't convert CLASS(*) to INTEGER(4) at (1)
utests/test_foul.f:317.7:

  rc = cassign (ra < rb, ra, rb)
       1
Error: Can't convert CLASS(*) to REAL(4) at (1)



                                         1
Error: CLASS variable 'c' at (1) must be dummy, allocatable or pointer
lib/foul.f:495.10:

      c = a
      1

Error: Nonallocatable variable must not be polymorphic in intrinsic
assignment at (1) -    check that there is a matching specific subroutine 
for '=' operator
lib/foul.f:497.10:

      c = b
      1

这是我编写的函数。变量ab 可以是任何类型 字符、整数或实数。并且输出类型应该匹配输入 ab 如果两种类型匹配,函数type_match (a, b) 返回真,否则返回假。

Function cassign (expr, a, b, wrn) Result (c)

  Logical, Intent(in) :: expr
  Class (*), Intent(in) :: a, b
  Logical, Intent (out), Optional :: wrn

  Class (*) :: c  

  Logical :: warn, tma, tmb 

  !!$ Perform warning tests (performs type matching).
  If (Present (wrn)) Then

    !!$ Matching input types. 
    tma = type_match (a, b)
    if (tma) Then

      tmb = type_match (a, c)

      !!$ Matching input and output types.
      If (tmb) Then
        If (expr) Then
          c = a
        Else
          c = b
        End If
        wrn = .False.

      !!$ Warning: Non-matching types.
      Else
        wrn = .True.
      End If

    Else

      wrn = .True.

    End If

  Else

    If (expr) Then
      c = a
    Else
      c = b
    End If

  End If

End Function cassign

【问题讨论】:

  • 您是否尝试过使c 可分配(如错误消息所示)?或者您是否试图不这样做,以便您可以以有趣的方式使用结果?
  • 我使用的是最新的 gfortran 4.9。
  • lib/foul.f:497.10: c = a 1 Error: Assignment to an allocatable polymorphic variable at (1) is not yet supported
  • 它似乎有效。但是我必须返回一个数组而不仅仅是一个变量。
  • gfortran -o build/utests/test_foul.o -c -ffree-form -g -J./build/lib utests/test_foul.f utests/test_foul.f:315.7: sc = cassign (ra &lt; rb, sa, sb) 1 Error: Can't convert CLASS(*) to CHARACTER(1) at (1)

标签: function class return fortran


【解决方案1】:

我不确定我是否建议按照我在下面写的那样做,而不是保留泛型,但我会尝试解释。

首先要注意的是,正如错误消息所述,对于非虚拟参数多态变量(例如c),该变量必须具有pointerallocatable 属性。在这里,函数结果为allocatable 是有意义的。

添加allocatable属性后,你似乎遇到了与可分配多态变量赋值相关的两件事:一次是在函数中设置结果,一次是使用函数的结果。

您使用的 gfortran 版本(显然)不支持对多态变量的内在赋值。你可以使用等价的,可以说它的意图更清晰:

allocate (c, source=a)  ! You may also need to provide bounds for c
                        ! for some gfortran.

这是函数中赋值问题的解法。

但是,使用函数结果,您现在返回的是多态结果。这意味着接受赋值的变量也必须是多态的,或者赋值不能是内在的。这是

错误:无法在 (1) 处将 CLASS(*) 转换为 INTEGER(4)

尝试内部赋值时出错。

要么让一切都成为多态的,要么坚持使用泛型,要么使用定义的赋值。下面是后一种情况的简化示例。 [根据需要调整和扩展。]

module hello_bob
  interface assignment(=)
    module procedure int_equal_func_class
  end interface

contains

  subroutine int_equal_func_class(a,b)
    integer, intent(out) :: a(:)
    class(*), intent(in) :: b(:)

    select type (b)
      type is (integer)
        a = b
    end select
  end subroutine int_equal_func_class

   function func(a)
     class(*), intent(in) :: a(:)
     class(*), allocatable :: func(:)

     ! No intrinsic assignment supported, also see note about bounds
     allocate(func, source=a)
   end function func

end module hello_bob

program bob
  use hello_bob
  integer i(4)

  i=func([1,2,3,4])
  print*, i

end program bob

【讨论】:

  • 在这个新的多态想法出现在我脑海中之前,我使用的是泛型。
  • 错误:尚不支持分配给 (1) 处的可分配多态变量
  • 我走在了我的时代前面,应该坚持通用。
  • 另外我不想在我的代码中有变通办法。如果目前不支持,我不会使用它。否则,它会产生不明显的并发症。此外,一旦该功能得到支持,旧代码不应再存在,而只保留分配给多态变量的代码。
  • 我同意糟糕的解决方法,但在这种情况下还不错(见里面的评论)。此外,添加定义的赋值与做泛型一样多,所以我真的建议使用后者。不过,选择还是不错的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多