问题描述
是否可以将过程存储为派生类型的属性?我正在考虑以下内容:
模块funcs_mod
public :: add
包含
函数add(y,z)结果(x)
整数,意图(in):: y,z
整数:: x
x = y + z
结束函数
结束模块
模块type_A_mod
使用funcs_mod
public :: type_A,set_operator
type type_A
procedure(),pointer,nopass ::操作符
结束类型
包含
子程序set_operator(A,操作符)
external :: operator
type(type_A),intent(inout):: A
A%运算符=>运算符
结束子程序
函数操作(A,y,z)结果(x)
类型(type_A),intent(in):: A
整数,意向(in) :: y,z
integer :: x
x = A运算符(y,z)
结束函数
结束模块
程序测试
使用type_A_mod
使用funcs_mod
type(type_A):: A
调用set_operator(A,add)
write(*,*)operate(A,1,2)
结束程序
但这不能成功编译。包含以下错误:
$ b $ 1)过程指针组件中的语法错误
和
2)'operator'at(1)不是'type_a'结构的成员。
除了一些不成功的用法声明。有没有办法做到这一点?任何帮助,我们将不胜感激。
更新:
code> procedure,指针到 procedure(),指针
,现在错误是
)1)FUNCTION属性与'operator'中的SUBROUTINE属性冲突
和
2)Can 't将UNKNOWN转换为INTEGER(4)
这两行代表 x = A%运算符(y,z)$ c $正如你发现的那样,声明一个过程指针声明的语法需要
procedure([接口]),指针[,...] :: ...
。您选择了 procedure(),指针,nopass :: operator
。
$ b
procedure()
是你没有声明 operator
是一个函数还是一个子例程。在这里没有任何不妥之处,但是更多的工作仍然在说服编译器说你一直在使用这些引用。您的编译器似乎不相信您。 与编译器认为你的意思不同,我会采取另一种方法。
对于具有该组件的类型的结构 A
,您引用 A%运算符
作为函数的结果操作
。你在声明这个后面的函数时说得清楚,它的结果是一个整数。
现在,假设你不想通过类型/类型转换来获得令人兴奋的结果对于这个整数结果,我们将把你总是打算使用 A%operator
作为一个带整数结果的函数。这意味着你可以声明那个过程指针组件是一个带整数结果的函数。
这仍然给你带来选择:
type type_A
$
procedure(integer),pointer,nopass :: operator
end type
是一个带整数结果和隐式接口的函数, type type_A
procedure(add),pointer,nopass :: operator
end type
是一个具有显式接口匹配功能的函数 add
。
您正在进行的设计选择会告诉您最终的决定。
最后一点,你并没有使用 implicit none
。当我们考虑您的产品线时,这一点很重要
external :: operator
如果 operator
是一个函数,那么(通过隐式输入规则)它有一个(默认)实际结果。所以,你想改变为以下之一:
integer,external :: operator
或
procedure(integer): :运营商
或
procedure(add):: operator
总结并回应评论弗拉基米尔F,仔细想想你的设计。您目前有来自操作
(在函数结果及其参数中)引用的约束,看起来您确实知道该组件将具有特定的接口。如果您确定,那么请使用程序(add)
作为声明/
Is it possible to store a procedure as a property of a derived type? I was thinking of something along the lines of:
module funcs_mod
public :: add
contains
function add(y,z) result (x)
integer,intent(in) :: y,z
integer :: x
x = y + z
end function
end module
module type_A_mod
use funcs_mod
public :: type_A,set_operator
type type_A
procedure(),pointer,nopass :: operator
end type
contains
subroutine set_operator(A,operator)
external :: operator
type(type_A),intent(inout) :: A
A%operator => operator
end subroutine
function operate(A,y,z) result(x)
type(type_A),intent(in) :: A
integer,intent(in) :: y,z
integer :: x
x = A%operator(y,z)
end function
end module
program test
use type_A_mod
use funcs_mod
type(type_A) :: A
call set_operator(A,add)
write(*,*) operate(A,1,2)
end program
But this doesn't successfully compile. Several errors are displayed including:
1) Syntax error in procedure pointer component
and
2) 'operator' at (1) is not a member of the 'type_a' structure
As well as some unsuccessful use statements. Is there a way to do this correctly? Any help is greatly appreciated.
UPDATE:
I've modified procedure,pointer
to procedure(),pointer
and now the errors are
1) FUNCTION attribute conflicts with SUBROUTINE attribute in 'operator'
and
2) Can't convert UNKNOWN to INTEGER(4)
Both refer to the line x = A%operator(y,z)
As you have discovered, the syntax for declaring a procedure pointer declaration requires procedure([interface]), pointer [, ...] :: ...
. You chose procedure(), pointer, nopass :: operator
.
The consequence of procedure()
is that you are not declaring whether operator
is a function or a subroutine. There is nothing untoward in this, but more work then remains in convincing the compiler that you are using the references consistently. Your compiler appears to not believe you.
Rather than go into detail of what the compiler thinks you mean, I'll take a different approach.
You reference A%operator
for a structure A
of type with that component as the result of the function operate
. You say clearly in declaring this latter function that its result is an integer.
Now, assuming that you don't want to do exciting things with type/kind conversion to get to that integer result, we'll take that you always intend for A%operator
to be a function with integer result. That means you can declare that procedure pointer component to be a function with integer result.
This still leaves you with choices:
type type_A
procedure(integer),pointer,nopass :: operator
end type
being a function with integer result and implicit interface, and
type type_A
procedure(add),pointer,nopass :: operator
end type
being a function with explicit interface matching the function add
.
Your ongoing design choices inform your final decision.
As a final note, you aren't using implicit none
. This is important when we consider your line
external :: operator
If operator
is a function then (by implicit typing rules) it has a (default) real result. So, you want to change to one of the following
integer, external :: operator
or
procedure(integer) :: operator
or
procedure(add) :: operator
To conclude, and echo the comment by Vladimir F, think very carefully about your design. You currently have constraints from the reference of operate
(in the function result and its arguments) that look like you really do know that the component will have a specific interface. If you are sure of that, then please do use procedure(add)
as the declaration/
这篇关于Fortran将过程另存为派生类型中的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!