函数结果中的 Fortran 类 (*) [英] Fortran Class (*) in Function Result

查看:27
本文介绍了函数结果中的 Fortran 类 (*)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am encountering an error with the function detailed in this post.

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

The problem occurs because I am trying to return a type corresponding to the input types. Can anyone suggest a solution? I originally had a function for each type, and then a generic interface to group them into the same name. Now I am trying to put everything in a single function using polymorphism.

这是 gfortran 给我的错误.

Here is the error that gfortran is giving me.

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)

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

I have tried to use an allocatable array. In the main program I then do

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.futests/test_foul.f:315.7:

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) 返回 true,否则返回 false.

Here is the function I have coded. The variables a and b can be any of the types Character, integer or real. And the output type should match the inputs a and b The function type_match (a, b) returns true if the two types match, false otherwise.

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

推荐答案

我不确定我是否建议做我在下面写的,宁愿保留泛型,但我会尝试解释.

I am not sure that I recommend doing what I write below, preferring instead keeping to generics, but I will attempt to explain.

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

The first thing to note is that, as the error message states, for a non-dummy argument polymorphic variable (such as c) that variable must have the pointer or allocatable attribute. Here, it makes sense for the function result to be allocatable.

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

After adding the allocatable attribute, you seem to experience two things related to assignment of the allocatable polymorphic variable: once in the function setting the result, and once using the result of the function.

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

The version of gfortran you are using doesn't (apparently) support intrinsic assignment to polymorphic variables. You can use the equivalent, which arguably has the intention even clearer:

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

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

This is the solution to the assignment problem in the function.

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

With the function result, however, you are now returning a polymorphic result. That means that the variable taking the assignment must also be polymorphic, or the assignment must not be intrinsic. This is the

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

Error: Can't convert CLASS(*) to INTEGER(4) at (1)

尝试内部赋值时出错.

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

Either make everything polymorphic, stick with generics, or use defined assignment. A simplified example follows for the latter case. [Adjust and extend as required.]

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

这篇关于函数结果中的 Fortran 类 (*)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆