功能结果中的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.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屋!