Как сделать результат функции элементом класса производного типа?

#pointers #types #fortran

#указатели #типы #fortran

Вопрос:

Я пытаюсь создать абстрактный элемент и иметь возможность работать, не указывая явно, что это за элемент; то есть, например, создать вектор и выполнить некоторую операцию с его элементами, независимо от того, что это за вектор.

Вот пример кода

 module reso
use, intrinsic :: iso_fortran_env, only: dp => real64
implicit none

type datos  
real(dp) :: x1,x2
integer :: longitud
contains
end type datos

abstract interface
function WW(r)
import
type(datos), intent(in) :: r
real(dp),dimension(r%longitud) :: WW
end function
end interface 

type vector
contains
procedure(WW),nopass, pointer :: vec=>linspace
end type

contains
function linspace(r) result (v)
type(datos), intent(in) :: r
real(dp),dimension(r%longitud) :: v
integer :: i
real(dp) :: incremento 
incremento = (r%x2-r%x1)/(real(r%longitud-1))
forall (i=1:r%longitud) v(i) = incremento*(i-1) r%x1
end function linspace

end module reso

module operation
use, intrinsic :: iso_fortran_env, only: dp => real64
use reso

implicit none

contains

function diff(r,c) result (dd)
type(vector),intent(in) :: r
type (datos),intent(in) :: c
real(dp), dimension(c%longitud-1) :: dd
integer:: i
do i = 1:c%longitud-1
dd(i) = r%vec(c)(i 1) - r%vec(c)(i)
end do
end function diff

end module operation


program main
use, intrinsic :: iso_fortran_env, only: dp => real64
use reso
use operation
type (datos) ::d
d%x1 = 5.0d0
d%x2 = 7.0d0
d%longitud = 3

type(vector) :: v

print*,  v%vec(d)
print*,  v%vec(d)(1)

print*, diff(v,d)

end program main
  

Основная идея этих модулей заключается в создании массива, и я хотел бы иметь возможность выполнять операции с результатом функции linspace . Вот почему я создаю указатель внутри type vector . Но это работает не так, как я ожидал, потому что у меня возникает следующая ошибка при компиляции с gfortran-8 :
procedure(WW),nopass, pointer :: vec=>linspace
1
Error: Expected binding attribute at (1)
Есть ли способ сделать это правильно и / или более аккуратно?

Комментарии:

1. Вы хотите, чтобы vec была процедурой с привязкой к типу или компонентом указателя на процедуру? Если первое, удалите pointer атрибут; если второе, удалите contains . Помимо этого, я не совсем понимаю, что вы намерены: не могли бы вы привести несколько других примеров того, чем вы надеетесь управлять?

2. @francescalus Я бы хотел создать объект, подобный тому, y%linspace где у него есть результат linspace . Я думаю, что более общим для моей цели было бы создать функцию, аргументом которой является массив, но без создания внутри функции, как, например, function (y) type(My_type),intent(in) :: y и y имеет массив, который я создал ранее, но используя, например, функцию linspace .

3.Несмотря на ошибку компилятора, обратите внимание, что dd(i) = r%vec(c)(i 1) - r%vec(c)(i) в каждом цикле функция vec будет выполняться дважды. Здесь нет «абстрагирования данных».