函数结果中的 Fortran 类 (*) [英] Fortran Class (*) in Function Result
问题描述
我遇到了这篇文章中详述的函数的错误.
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
这是我编写的函数.变量 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
),该变量必须具有 pointer
或 allocatable
属性.在这里,函数结果是 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屋!