首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Fortran 2003中的内部赋值和多态性

Fortran 2003中的内部赋值和多态性
EN

Stack Overflow用户
提问于 2018-04-03 02:09:23
回答 3查看 754关注 0票数 2

我尝试向由@VladimirF编写的this module添加一个过程,该过程在Fortran2003中实现了一个通用链表。

代码语言:javascript
复制
  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给出以下错误:

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

我不熟悉F2003+中的多态性,因此我不理解错误消息或其上下文。哪里出了问题,如何才能修复?

EN

回答 3

Stack Overflow用户

发布于 2018-04-03 06:10:43

错误消息就是它所说的意思。Fortran2008标准描述了内部赋值语句,它说:“如果变量是多态的,它应该是可分配的,而不是一个共数组”arrayOut是CLASS(*),这使得多态。只能将可分配的多态性分配给。

至于“如何修复它”,这需要更多的上下文。

票数 3
EN

Stack Overflow用户

发布于 2018-04-03 15:37:07

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

代码语言:javascript
复制
arrayOut(i) = nodeIter%item

是一个内部赋值语句。

Fortran 2008 (不是Fortran 2003)允许此语句左侧的变量是多态的。这里的arrayOut(i)是(无限)多态的。然而,在允许对多态变量赋值时,有一个限制(F2008,7.2.1.1 (1)):

如果变量是多态的,则它应该是可分配的,而不是共数组

本例中的编译器出现问题是因为arrayOut(i)不可分配。但是,即使将arrayOut设置为可分配也无济于事:arrayOut(i)是数组的一个元素,永远不会是可分配的。

你想在这里简单地做的事情,是做不到的。在为数组元素赋值时,不能保证数组中的每个元素与其他元素的类型完全相同,这一点应该很清楚。这是Fortran数组的要求,即使是多态数组也是如此。

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

  • 使编译器相信所有元素都是同一类型的;
  • 使用数组容器。

后者,就像

代码语言:javascript
复制
type stuff
  class(*), allocatable :: item
end type stuff
type(stuff) arrayOut(length)

在其他上下文中出现的问题和答案在这里。

为了“令人信服”,你需要让左边不是多态的。

票数 2
EN

Stack Overflow用户

发布于 2018-04-03 19:28:16

我认为其他答案很好地描述了这个问题。不能赋值给多态的不可分配变量。并且数组元素永远不是可分配的。

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

作为该库的用户,一旦知道所有元素都属于同一类型,就有两种可能

  1. 使用同一个库中的参数列表
  2. 为数组中可能出现的每种类型创建自己的函数。不是在库中,而是在您自己的代码中。您必须保证所有元素都属于该类型。

子例程integer_list_as_array( self,arrayOut)类(List),intent(inout) ::self整数,尺寸(1:self%length),intent(out) ::arrayOut ...结束子例程integer_list_as_array

如果有人知道一个通用的技巧,只是假设所有的元素都是相同的类型,但没有指定类型,我想知道。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49616410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档