Встала задача такой организации вычислений, когда вызов необходимой процедуры следует осуществлять по индексу.
Фактически — необходимо создать массив указателей на процедуры.
В Фортране это затруднено тем, что описание вроде
real, pointer, dimension(:) :: a
задаёт не массив указателей на объекты вещественного типа, а указатель на вещественный массив.
Однако, ситуация разрешима в рамках стандарта F2003.
Для этого необходимо описать структуру, содержащую поле — указатель на процедуру соответствующего вида.
После чего организовать массив таких структур. Соответственно, после присвоения указателей, вызов процедуры будет выглядеть как обращение к полю-указателю соответствующего элемента массива.
Чтобы создать указатель на процедуру (поле задаваемой структуры), необходимо описать интерфейс указанной процедуры. Так как процедур у нас несколько, ситуация разрешается через описание абстрактного интерфейса.
В общем виде решение на примере может выглядеть так, как это показано ниже.
funcs.f90
Записываем модуль, содержащий две функции, общий (одинаковый) для них абстрактный интерфейс и новый тип func_pointer, содержащий только одно поле f_pointer — указатель на процедуру, имеющую интерфейс наших функций.
module funcs implicit none ! Описываем универсальный (абстрактный) интерфейс ! для используемых процедур abstract interface function func (a,b) result (c) real :: a, b, c end function func end interface ! Вводим новый тип, задающий указатель на процедуру, ! описанную в интерфейсе type func_pointer procedure (func), pointer, nopass :: f_pointer end type contains ! Задаём пару функций для примера. function plus (x,y) result (p) real :: x, y, p p = x + y end function plus function minus (x,y) result (m) real :: x, y, m m = x-y end function minus end module funcs
main.f90
В основной программной единице описываем массив типа func_pointer, размещаем его и присваиваем полю f_pointer каждого из элементов массива указатель на соответствующую функцию. Теперь вызов функции может осуществляться через обращение к массиву functions с указанием индекса и поля-указателя.
program test use funcs implicit none ! Создаём массив типа func_pointer -- массив ! указателей на процедуры type(func_pointer), dimension(:), allocatable :: functions integer :: i real :: x, y ! Размещаем массив и присваиваем его элементам ! указатели на соответствующие процедуры allocate (functions(2)) functions(1) % f_pointer => plus functions(2) % f_pointеr => minus read (*,*) i, x, y ! Вызываем процедуру через указатель по её индексу write (*,*) functions(i) % f_pointer(x,y) end program test