Я пытаюсь создать гетерогенные массивы, содержащие переменные разных типов, например, [ 1.0, 7, "hi" ]
. Я попытался включить class(*)
или type(*)
в конструктор массива (см. Конец следующего кода), но gfortran5.2 просто рассматривает его как синтаксическую ошибку. Есть ли способ сделать такой массив с конструктором массива или необходимо использовать другой подход (например, определить тип, содержащий каждый элемент отдельно)?Создание гетерогенных массивов в Fortran
Подробнее:
Следующий код является примером, почему я хочу создать такой массив. Процедура checktype_multi
принимает несколько аргументов с ключевым словом optional
, но этот подход явно ограничен из-за фиксированного количества аргументов. Чтобы разрешить произвольное количество аргументов, я попробовал процедуру checktype_array
, но, похоже, невозможно передать массив с разными типами ... Более практичным case может быть создание подпрограммы для печати переменного количества аргументов с различными типами.
module mymod
implicit none
contains
subroutine checktype (x)
class(*) :: x
select type (x)
type is (integer) ; print *, "int : ", x
type is (real) ; print *, "real : ", x
type is (character(*)) ; print *, "string : ", x
endselect
end subroutine
subroutine checktype_multi (x1, x2, x3)
class(*), optional :: x1, x2, x3
print *
if (present(x1)) call checktype (x1)
if (present(x2)) call checktype (x2)
if (present(x3)) call checktype (x3)
end subroutine
subroutine checktype_array (a)
class(*) :: a(:)
integer :: k
print *
do k = 1, size(a)
call checktype (a(k))
enddo
end subroutine
end module
program main
use mymod
call checktype_multi (1.0)
call checktype_multi (1.0, 7)
call checktype_multi (1.0, 7, "hi")
! call checktype_array ([ 1.0, 7, "hi" ]) !! error (this is to be expected)
!>>> Here is the problem.
! call checktype_array ([ type(*) :: 1.0, 7, "hi" ]) !! this is also an error
! call checktype_array ([ class(*) :: 1.0, 7, "hi" ]) !! this too
end program
Привет @IanH, спасибо очень много для вас информации. Поскольку подпрограмма 'checktype_multi' могла получать литералы разных типов (например, 1.0 и 7) непосредственно в качестве фактических аргументов, я представил себе, что они могут быть преобразованы внутри (внутри компилятора) в некоторые внутренние объекты C, которые представляют эти данные (например , что-то вроде 'struct', состоящего из указателя на необработанные данные и некоторой информации времени выполнения). (продолжение) – roygvib
Итак, я задавался вопросом, есть ли какие-либо удобные способы прямого создания массива гетероформатов Fortran, например массив, состоящий из внутренних объектов, на которые ссылается класс (*) (как некоторая новая функция Fortran). Но, по вашему мнению, это не так. Большое спасибо :) – roygvib
И еще один вопрос: gfortran5.2 все еще дает ошибку с вашим кодом («Невозможно преобразовать целое число в класс (*)» и т. Д.), Но является ли это тем, что gfortran5.2 все еще находится за последним стандартом? Поскольку у меня есть только ifort14 (и не могу установить более новые версии в моей среде), я задался вопросом, не компилируется ли код с более новыми компиляторами. (Если нужны более явные коды, я сделаю это вопросом.) – roygvib