Fortran 2003中的内在赋值和多态性

时间:2018-04-02 18:09:23

标签: fortran polymorphism intel-fortran

我尝试向this module添加一个由@VladimirF编写的过程,该过程在Fortran 2003中实现了一个通用的链表。为了方便起见,我想能够将列表的内容输出为数组,所以我将以下过程添加到名为lists.f90的文件中的列表模块中:

  subroutine list_as_array(self, arrayOut)
    class(list),intent(inout) :: self
    class(*),dimension(1:self%length),intent(out) :: arrayOut
    integer :: i
    type(list_node), pointer :: nodeIter
    nodeIter = self%first
    do i = 1,self%length
      arrayOut(i) = nodeIter%item  ! <---ERROR here
      if (i<self%length) then
        nodeIter = nodeIter%next
      end if
    end do
  end subroutine list_as_array

ifort 18.0.0出现以下错误:

lists.f90(324): error #8304: In an intrinsic assignment statement, variable shall not be a non-allocatable polymorphic.   [ARRAYOUT]
      arrayOut(i) = nodeIter%item
------^

我是F2003 +中的多态的新手,所以我不理解错误信息或其上下文。怎么了,怎么修好?

3 个答案:

答案 0 :(得分:2)

错误消息表示它所说的内容。描述内在赋值语句的Fortran 2008标准说:&#34;如果变量是多态的,它应该是可分配的而不是一个共同的&#34; arrayOut是CLASS(*),它具有多态性。只能分配可分配的多态性。

至于&#34;如何修复它&#34;,这需要更多的背景。

答案 1 :(得分:2)

首先,关于错误消息。在没有一些已定义的赋值的情况下,语句

arrayOut(i) = nodeIter%item

是一个内在的赋值语句。

Fortran 2008(不是Fortran 2003)允许此语句左侧的变量具有多态性。 arrayOut(i)这里是(无限制的)多态。但是,在允许赋值给多态变量时存在限制(F2008,7.2.1.1(1)):

  

如果变量是多态的,那么它应该是可分配的而不是一个共同的

在这种情况下,编译器抱怨,因为arrayOut(i)不可分配。但是,即使使arrayOut可分配也无济于事:arrayOut(i)是数组的一个元素,永远不会被分配。

你想在这里做什么,不能做。这一点应该清楚,因为在分配数组元素时,您并不能保证数组的每个元素都与其他元素完全相同。这是Fortran数组的要求,甚至是多态数组。

关于如何做你想做的事,有几种方法:

  • 说服编译器所有元素都属于同一类型;
  • 使用数组容器

后者,如

type stuff
  class(*), allocatable :: item
end type stuff
type(stuff) arrayOut(length)

在问题的其他背景下出现并在这里回答。

对于“令人信服”,你需要使左侧非多态。

答案 2 :(得分:2)

我认为其他答案很好地描述了这个问题。无法分配多态非可分配变量。并且数组元素永远不可分配。

我已经考虑过如何做这样的事情,但是我没有想出一个令人满意的解决方案如何在库中创建这样的函数。主要问题是没有类型保护只会检查两个实体的动态类型是否相同。您必须在SELECT TYPE中指定实际类型。

作为图书馆的用户,一旦您知道所有元素属于同一类型,您就有两种可能性

  1. 使用同一个库中的参数列表

  2. 为可出现在数组中的每种类型创建自己的函数。不是在库中,而是在您自己的代码中。您必须承诺所有元素都属于该类型。

    subroutine integer_list_as_array(self, arrayOut)
      class(list),intent(inout) :: self
      integer,dimension(1:self%length),intent(out) :: arrayOut
      ...
    end subroutine integer_list_as_array
    
  3. 如果有人知道这样做的伎俩,只是假设所有元素属于同一类型,但没有指定类型,我想知道。