在 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" 是稍微清楚一点。不过,这是一个更易于访问的文档和一个可行的替代方案。
如标题所述,我想直接修改我通过从函数检索的指针访问的数据。 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" 是稍微清楚一点。不过,这是一个更易于访问的文档和一个可行的替代方案。