2017-04-24 48 views
1

让我们假设我有一个派生类型Coordinates与它的类型绑定过程swap:现在呼叫类型绑定程序derrived类型的Fortran语言的数组

module myTypes 
    implicit none 
    public :: Coordinates 

    type Coordinates 
     real :: x,y 
    contains 
     procedure :: swap ! Error here 
    end type 
contains 
    subroutine swap(this) 
     class (Coordinates) :: this 
     this%x = this%x + this%y 
     this%y = -(this%y - this%x) 
     this%x = this%x - this%y 
    end subroutine 
end module 

,如果我有叫Coordinates实例point_A,如果我想为它调用类型绑定过程swap,我只会写:call point_A%swap。但是,如果我有Coordinates实例的数组,如:

type(Coordinates), dimension(:), allocatable :: setOfPoints 

然后调用swapsetOfPoints所有元素,我想这样写:

call setOfPoints(:)%swap 

为了实现这一目标,我将swap程序的代码更改为:

subroutine swap(these) 
     class (Coordinates), dimension(:) :: these 
     integer :: i 
     do i = 1, size(this) 
      this(i)%x = this(i)%x + this(i)%y 
      this(i)%y = -(this(i)%y - this(i)%x) 
      this(i)%x = this(i)%x - this(i)%y 
     end do 
end subroutine 

不幸的是,gfortran不喜欢我的想法。在我标志着第一段代码,它说行:

Error: Passed-object dummy argument of 'swap' must be scalar. 

问:我怎么能要求派生类型一次的所有实例的类型绑定程序?我不想把这个调用放到循环中,但是我想像之前写的那样执行此操作,就像我们在Fortran中对数组执行的操作一样。

我读了关于ELEMENTAL关键字,但如果我想使用它,我需要类型绑定过程是'纯',这不是我的情况。 我试图把一个DEFERRED关键字词procedure后,但随后编译器说:

Error: Interface must be specified for DEFERRED binding 

我创建了一个接口,用于swap,但我无法弄清楚在何处放置它。我尝试了很多职位,编译器说'界面在那里出乎意料'。 另外,我读了约SELECT TYPE,但我认为它不会帮助我的情况。

回答

1

你具体的例子是完全没有用元素

module myTypes 
    implicit none 
    public :: Coordinates 

    type Coordinates 
     real :: x,y 
    contains 
     procedure :: swap ! Error here 
    end type 
contains 
    elemental subroutine swap(this) 
     class (Coordinates), intent(inout) :: this 
     this%x = this%x + this%y 
     this%y = -(this%y - this%x) 
     this%x = this%x - this%y 
    end subroutine 

end module 

use myTypes 

type(Coordinates) :: arr(10) 

arr = Coordinates(1.,2.) 

call arr%swap 

end 

你的子程序是纯粹的。如果不能,请考虑使用impure elemental

+0

非常感谢! “不纯的元素”对我来说工作得很好! P.S .:的确,在这里我省略了一些使子程序不纯的行 – Georgy