本文介绍了Fortran将过程另存为派生类型中的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以将过程存储为派生类型的属性?我正在考虑以下内容:

 模块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) 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将过程另存为派生类型中的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 20:02