【问题标题】:Creating heterogeneous arrays in Fortran在 Fortran 中创建异构数组
【发布时间】:2015-11-10 01:07:20
【问题描述】:

我正在尝试创建包含不同类型变量的异构数组,例如[ 1.0, 7, "hi" ]。我试图在数组构造函数中包含class(*)type(*)(请看下面代码的末尾),但gfortran5.2只是将其视为语法错误。有没有办法用数组构造函数来制作这样的数组,或者是否需要使用不同的方法(例如,定义一个单独包含每个元素的类型)?


更多细节:

以下代码是我要创建这样一个数组的示例。 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

【问题讨论】:

    标签: arrays fortran heterogeneous


    【解决方案1】:

    数组的元素只能在值上有所不同。它们不能在类型或任何其他属性上有所不同。

    相反,使用派生类型包装器围绕无限多态可分配组件。然后组件的动态类型被认为是包装器类型的对象值的一部分。

    TYPE :: wrapper
      CLASS(*), ALLOCATABLE :: item
    END TYPE wrapper
    
    CALL sub([wrapper(1), wrapper(2.0), wrapper('3')])
    

    (数组构造函数(或结构构造函数)指定一个值。一个值本身不能是多态的,值的类型始终只是该值的类型。可选前导的语法type-spec数组构造函数中的 em> 反映了这一点,因为它只是一个 type-spec,而不是 declaration-type-spec。)

    【讨论】:

    • 嗨@IanH,非常感谢您提供的信息。因为checktype_multi 例程能够直接接收不同类型的文字(如 1.0 和 7)作为实际参数,所以我想它们可能会在内部(在编译器中)转换为一些表示这些数据的内部 C 对象(例如,类似于struct,由指向原始数据的指针和一些运行时信息组成)。 (续)
    • 所以我想知道是否有任何方便的方法可以直接构造异类数据的 Fortran 数组,例如,由 class(*) 引用的内部对象组成的数组(作为一些较新的 Fortran 功能)。但根据您的回答,情况似乎并非如此。非常感谢:)
    • 还有一个问题:gfortran5.2 的代码仍然出错(“无法将整数转换为 Class(*)”等),但这是因为 gfortran5.2 仍然落后于最新标准吗?因为我只有 ifort14(并且无法在我的环境中安装更新版本),我想知道代码是否可以直接使用更新的编译器编译。 (如果需要更明确的代码,我会提出问题。)
    • 另一个问题(很抱歉... *) 标量?如果是这样,恐怕我也犯了class(*) :: a(:)的大错误......(这可能类似于type(T), pointer :: a(:)表示指向type(T) :: a(...)的指针而不是指向类型的指针数组( T) 标量。)
    • gfortran 还不是 Fortran 2003(或 Fortran 2008)编译器。当前主干似乎不支持通过结构构造函数定义无限多态组件。我认为我的回答的第一句话也回答了另一个问题 - 数组的所有元素必须具有相同的 [动态和声明] 类型。
    猜你喜欢
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 2018-02-06
    • 2018-02-24
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多