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

查看:194
本文介绍了功能结果中的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.f
utests / 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

这里是我编码的函数。变量 a b 可以是任何类型
字符,整数或实数。并且输出类型应该匹配输入 a b
函数 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 ),变量必须指针可分配属性。这里,函数结果为可分配是有意义的。

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.

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

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)

要么使一切多样化,要么使用泛型,要么使用一种方法:$ b

error when you try intrinsic assignment.

定义分配。后一种情况的简化示例如下。

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

   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天全站免登陆