Creating heterogeneous arrays in Fortran

I am trying to create heterogeneous arrays containing variables of different types, for example [ 1.0, 7, "hi" ]. I tried to include class(*)either type(*)in the array constructor (see the end of the following code), but gfortran5.2 just treats it as a syntax error. Is there a way to make such an array with an array constructor, or is it necessary to use a different approach (for example, to determine the type that contains each element separately)?


More details:

The following code is an example of why I want to create such an array. A routine checktype_multireceives several arguments with a keyword optional, but this approach is clearly limited due to a fixed number of arguments. To allow an arbitrary number of arguments, I tried a procedure checktype_array, but it seems impossible to pass an array with different types ... A more practical case might be to create a routine to print a variable number of arguments with different types.

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
+4
source share
1 answer

Elements of the array can only differ from each other in value. They cannot differ in type or other attribute.

. .

TYPE :: wrapper
  CLASS(*), ALLOCATABLE :: item
END TYPE wrapper

CALL sub([wrapper(1), wrapper(2.0), wrapper('3')])

( ( ) . , . , , , .)

+4

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


All Articles