在 fortran 中有一个函数 return 可以放在赋值的 left-hand-side 上的引用

Have a function in fortran return a reference that can be placed on the left-hand-side of an assignment

如标题所述,我想直接修改我通过从函数检索的指针访问的数据。 l.h.s 上出现的函数返回引用。赋值 (=) 在 C++ 中没有问题,但以下 Fortran 中的最小示例会出错:

module test_mod
  implicit none

  integer, target :: a=1, b=2, c=3 ! some member variables

contains

  function get(i)
    integer, pointer :: get
    integer, intent(in) :: i

    select case (i)
      case (1)
        get => a
      case (2)
        get => b
      case (3)
        get => c
    end select 
  end function get

end module test_mod

program test
  use test_mod
  implicit none
  integer, pointer :: i_p

  !> prints out 1 2 3
  print*, get(1), get(2), get(3)

  !> this is what I want but I get the error
  !> Error: 'get' at (1) is not a variable
  get(2) = 5

  !> this works but is not what I want
  i_p => get(2)
  i_p = 5

end program test

有什么办法可以实现这种行为吗?也许我缺少一些属性?我想绕过编写任何 setter 例程,例如

set(i,value)

因为它应该模仿数组的外观。 在我的应用程序中,成员变量a,b,c实际上是不同大小的数组

a = [a1, a2, a3]
b = [b1, b2]
c = [c1]

我希望 getter get(i,j) 模仿指针矩阵

        j = 1   2   3

i = 1:   [[a1, a2, a3],
i = 2:    [b1, b2, XX],
i = 3:    [c1, XX, XX]]

我们 XX 将引用 null()

更新: 我使用的是 gfortran(版本 5.2.0),部署机器的版本只能从 4.6.x 开始及以上。因此,不幸的是,我无法使用建议的 Fortran 2008 标准功能。是否可以在没有开箱即用的编译器支持的情况下模仿上述行为?

更新二: 所以我最终实现了如下结构

type Vec_t
  integer, allocatable, dimension(:) :: vec
end type Vec_t
type(Vec_t), allocatable, dimension(:), target :: data

我这样初始化的(我最后提到的三角矩阵应用程序)

allocate(data(max))
do i=1,max
  allocate(data(i)%vec(i))
end do

我通过

访问和写入它
print*, data(2)%vec(1)
data(2)%vec(1) = 5

这不是我想要的,但对我的申请来说已经足够好了。

让我们看看你想做什么:

get(2)=5

和错误信息

Error: 'get' at (1) is not a variable

这看起来很全面:你不能随心所欲。或者,也许...

根据 Fortran 2003 的规则,

get(2) 确实不是变量。在 Fortran 2003 中,变量由规则 R601 和 R603 给出,它们是指示符列表。

赋值的左侧必须是变量。

但看看 Fortran 2008 及其对变量的定义。现在一个变量要么是那些相同的指示符之一(或与 coarrays 或复杂部分相关的指示符),但它也可以(C602 到 R602)是一个函数引用

shall have a data pointer result.

这在 Fortran 2008 的介绍中有所总结,详细介绍了对 Fortran 2003 的扩展,如

A pointer function reference can denote a variable in any variable definition context.

get(2) 是对具有数据指针结果的函数的引用。根据 Fortran 2008 的规则,get(2) then 可能出现在赋值语句的左侧。

唉,目前的编译器对 Fortran 的这种解释是 not widely supported:在回答 Cray 编译器时。

这意味着这个答案实际上是在说您有两个选择:切换编译器或等到此功能得到更广泛的使用。由于这两种方法都可能不切实际,您可能需要另一个答案,它提供了一些更便携的解决方法。

我更喜欢我的 link 而不是 innoSPG 给出的 that,因为虽然后者是基于前者,但相应字段的描述 "Pointer functions - pointer function ref is a variable" 是稍微清楚一点。不过,这是一个更易于访问的文档和一个可行的替代方案。