Fortran saves the procedure as a property in a derived type

Is it possible to save a procedure as a property of a derived type? I was thinking of something like:

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 fails to compile. Several errors are displayed, including:

1) Syntax error in the component of the procedure pointer

and

2) the β€œoperator” in (1) is not a member of the type_a structure

Like some unsuccessful usage statements. Is there any way to do this right? Any help is appreciated.

UPDATE:

I changed procedure,pointer to procedure(),pointer , and now the errors

1) FUNCTION attribute conflicts with SUBROUTINE attribute in 'operator'

and

2) Unable to convert UNKNOWN to INTEGER (4)

Both relate to line x = A%operator(y,z)

+1
source share
1 answer

As you discovered, the syntax for declaring a procedure pointer declaration requires procedure([interface]), pointer [, ...] :: ... You have selected procedure(), pointer, nopass :: operator .

The consequence of procedure() is that you do not declare whether operator function or subroutine. There is nothing unpleasant about this, but more work remains to convince the compiler that you use links in sequence. Your compiler does not seem to believe you.

Instead of explaining in detail about the compiler you are thinking about, I will take a different approach.

You refer to the A%operator on an A type structure with this component as a result of the operate function. You say clearly by declaring this last function that its result is an integer.

Now, assuming that you do not want to do interesting things with type / type conversion in order to get to this integer result, we will assume that you always intend to use A%operator as a function with an integer result. This means that you can declare that the component of the procedure pointer is a function with an integer result.

This still leaves you a choice:

 type type_A procedure(integer),pointer,nopass :: operator end type 

- a function with an integer result and an implicit interface, and

 type type_A procedure(add),pointer,nopass :: operator end type 

is a function with an explicit interface corresponding to the add function.

Your current design options tell you the final decision.

As a final note, you are not using implicit none . This is important when we review your string.

 external :: operator 

If operator is a function, then (by implicit input rules) it has a real result (by default). So you want to go to one of the following

 integer, external :: operator 

or

 procedure(integer) :: operator 

or

 procedure(add) :: operator 

In conclusion, and I will repeat the comment of Vladimir F, think carefully about your design. Currently, you have restrictions on the operate link (as a result of the function and its arguments) that look like you really know that the component will have a specific interface. If you are sure about this, then use procedure(add) as the declaration /

+1
source

Source: https://habr.com/ru/post/1246985/


All Articles