“传递对象伪参数必须是标量”

时间:2018-01-26 14:24:10

标签: fortran

我有类型绑定的程序,我想接受一个数组作为传递的伪参数(getMeanassignEachThatInThis下面)。这不会编译。我读过Metcalf et al。,并且他们并没有说传递的伪参数必须是标量,而我真的不明白为什么必须如此。

如果我使用nopass属性进行编译,那么当程序不是类型绑定的时候就会这样做。

有人可以解释一下发生了什么,做什么不安全?

以下是我的例子:

module types
implicit none

integer, parameter :: DP = selected_real_kind(r=250,p=13)

type :: my_type1

        real(KIND=DP), dimension(:),   allocatable :: elem1    ! interest rate

    contains

        procedure :: getMean        => getMean_my_type1 

        procedure ::                   assignThatInThis_my_type1
        procedure ::                   assignEachThatInThis_my_type1
        generic   :: assignment (=) => assignThatInThis_my_type1, assignEachThatInThis_my_type1

end type my_type1

contains

subroutine assignThatInThis_my_type1(this,that)
        ! Defines the overloaded `=` operator for the 'my_type1' class
        ! this = that

   class(my_type1), intent(inout) :: this
   class(my_type1), intent(in)    :: that

   this%elem1  = that%elem1

end subroutine assignThatInThis_my_type1

subroutine assignEachThatInThis_my_type1(this,that)
        !--> this is apparently illegal, 'this' has to be a scalar :-(
        !--> in principle it could work with the 'nopass' attribute (see 'getMean_my_type1') but that won't work with the assignment operator '='

   class(my_type1), dimension(:), intent(inout) :: this
   class(my_type1), dimension(:), intent(in)    :: that

   integer :: i

   do i = 1,size(this,1)
      this(i) = that(i)
   end do

end subroutine assignEachThatInThis_my_type1


subroutine getMean_my_type1(this,that)

   class(my_type1), dimension(:), intent(inout) :: this
   class(my_type1),               intent(inout) :: that

   integer :: nTypes
   integer :: n
   integer :: j

   nTypes = size(this,1)
   n      = size(this(1)%elem1,1)    ! length of the simulation

   ! sum all elem1
   do j = 1,nTypes
      that%elem1 = that%elem1 + this(j)%elem1
   end do

   ! divide by the number of elements
   that%elem1 = that%elem1 / real(nTypes)

end subroutine getMean_my_type1


end module types


program pdatest
implicit none


end program pdatest

以下工作,我使用nopass的{​​{1}}属性,并且没有类型绑定的赋值子例程:

getMean

1 个答案:

答案 0 :(得分:1)

首先,由于Fortran的规则,传递对象的虚拟对象必须是标量(等等)。考虑F2008,C456:

  

传递对象伪参数应为标量,非指针,不可分配的虚拟数据对象,其声明类型与定义的类型相同; ...

使用nopass属性,类型绑定过程引用没有传递对象,因此此限制不适用。同样,如果您使子例程引用不是来自其类型绑定,则限制不适用。

使用getMean绑定,希望将数组缩减为标量,但是通过赋值,希望有一个输入数组和相同形状的输出数组。后者是元素子例程的一种情况。