通过 type/kind/rank 以外的方式区分 Fortran 中的泛型
Distinguishing generics in Fortran by other than type/kind/rank
我 巨大 使用非 1
索引 ALLOCATABLE
数组,我想知道其实际的下限(因此上限)它们作为 IN
/INOUT
args 提供的过程(所以我将这些虚拟参数声明为延迟形状数组,以使它们与它们的边界一起传递;参见 f_deferred_all
示例代码)。
但是
有时这些过程(在数据声明部分之后)可以处理作为子数组的实际参数,因此当需要时,我通常最终会复制该过程,更改其参数声明及其名称( cf. 程序 f_assumed
)。最好通过 INTERFACE
将两个过程放在同一个名称下。但是 standard 说我不能,因为
Interfaces of specific procedures or bindings are distinguished by
fixed properties of their arguments, specifically type, kind type
parameters, rank, and whether the dummy argument has the POINTER or
ALLOCATABLE attribute.
在下面的示例程序中,我通过使用指针实际参数和虚拟参数(参见 f_deferred_ptr
)克服了这个 "limitation"。
- 这 "solution" 是否以某种方式被弃用、劝阻、危险或其他?我问这个是因为我真的没怎么用过
POINTER
s。
此外,我定义了一个pntr
函数,它returns一个POINTER
到它的唯一(非ALLOCATABLE
数组或数组的一部分)IN
put 参数,这样我就可以使用它 "in-line" 而无需在主程序中定义 POINTER
并且我不必将 TARGET
属性放在实际参数上。
- 是否可以通过使用
pntr
创建一个临时数组?我想是的,但我不确定在主程序中定义 POINTER
并将其关联是否会在这方面产生影响。
- possible/is planned/would 更改标准以允许泛型之间的这种区分是否有意义? post 哪里有这样的建议,如果它们有意义的话?
示例如下。
module mymod
implicit none
interface f
module procedure f_deferred_all, f_deferred_ptr!, f_assumed
end interface f
contains
integer function f_assumed(x) result(y)
integer, dimension(:), intent(in) :: x
y = lbound(x,1)
end function f_assumed
integer function f_deferred_ptr(x) result(y)
integer, pointer, dimension(:), intent(in) :: x
y = lbound(x,1)
end function f_deferred_ptr
integer function f_deferred_all(x) result(y)
integer, allocatable, dimension(:), intent(in) :: x
y = lbound(x,1)
end function f_deferred_all
function pntr(v) result(vp)
integer, dimension(:), target, intent(in) :: v
integer, dimension(:), pointer :: vp
vp => v
end function pntr
end module mymod
program prog
use mymod
implicit none
integer :: i
integer, dimension(-5:5) :: v1
integer, dimension(:), allocatable :: v2
v1 = [(i, i = 1, 11)]
allocate(v2, source = v1)
print *, 'f_assumed(v1)', f_assumed(v1)
print *, 'f(pntr(v1))', f(pntr(v1(:))) ! is a temporary created?
print *, 'f(v2)', f(v2)
end program prog
您的示例代码不符合规范,因为特定名称 F_DEFERRED_PTR
和 F_DEFERRED_ALL
不明确。 Technical Corrigendum f08/0001 更改了“12.4.3.4.5 对通用声明的限制”中的措辞,将“ 而不是 INTENT(IN) 属性”添加到
Two dummy arguments are distinguishable if
• one is a procedure and the other is a data object,
• they are both data objects or known to be functions, and neither is TKR compatible with the other,
• one has the ALLOCATABLE attribute and the other has the POINTER attribute and not the INTENT(IN) attribute, or
• one is a function with nonzero rank and the other is not known to be a function.
这是由于 POINTER、INTENT(IN) 虚拟变量的实参可以是指针或指针赋值语句中虚拟指针的有效目标(12.5.2.7 指针虚拟变量 J3/10-007r1). Links to the discussion and resolution 的问题。
我 巨大 使用非 1
索引 ALLOCATABLE
数组,我想知道其实际的下限(因此上限)它们作为 IN
/INOUT
args 提供的过程(所以我将这些虚拟参数声明为延迟形状数组,以使它们与它们的边界一起传递;参见 f_deferred_all
示例代码)。
但是
有时这些过程(在数据声明部分之后)可以处理作为子数组的实际参数,因此当需要时,我通常最终会复制该过程,更改其参数声明及其名称( cf. 程序 f_assumed
)。最好通过 INTERFACE
将两个过程放在同一个名称下。但是 standard 说我不能,因为
Interfaces of specific procedures or bindings are distinguished by fixed properties of their arguments, specifically type, kind type parameters, rank, and whether the dummy argument has the POINTER or ALLOCATABLE attribute.
在下面的示例程序中,我通过使用指针实际参数和虚拟参数(参见 f_deferred_ptr
)克服了这个 "limitation"。
- 这 "solution" 是否以某种方式被弃用、劝阻、危险或其他?我问这个是因为我真的没怎么用过
POINTER
s。
此外,我定义了一个pntr
函数,它returns一个POINTER
到它的唯一(非ALLOCATABLE
数组或数组的一部分)IN
put 参数,这样我就可以使用它 "in-line" 而无需在主程序中定义 POINTER
并且我不必将 TARGET
属性放在实际参数上。
- 是否可以通过使用
pntr
创建一个临时数组?我想是的,但我不确定在主程序中定义POINTER
并将其关联是否会在这方面产生影响。 - possible/is planned/would 更改标准以允许泛型之间的这种区分是否有意义? post 哪里有这样的建议,如果它们有意义的话?
示例如下。
module mymod
implicit none
interface f
module procedure f_deferred_all, f_deferred_ptr!, f_assumed
end interface f
contains
integer function f_assumed(x) result(y)
integer, dimension(:), intent(in) :: x
y = lbound(x,1)
end function f_assumed
integer function f_deferred_ptr(x) result(y)
integer, pointer, dimension(:), intent(in) :: x
y = lbound(x,1)
end function f_deferred_ptr
integer function f_deferred_all(x) result(y)
integer, allocatable, dimension(:), intent(in) :: x
y = lbound(x,1)
end function f_deferred_all
function pntr(v) result(vp)
integer, dimension(:), target, intent(in) :: v
integer, dimension(:), pointer :: vp
vp => v
end function pntr
end module mymod
program prog
use mymod
implicit none
integer :: i
integer, dimension(-5:5) :: v1
integer, dimension(:), allocatable :: v2
v1 = [(i, i = 1, 11)]
allocate(v2, source = v1)
print *, 'f_assumed(v1)', f_assumed(v1)
print *, 'f(pntr(v1))', f(pntr(v1(:))) ! is a temporary created?
print *, 'f(v2)', f(v2)
end program prog
您的示例代码不符合规范,因为特定名称 F_DEFERRED_PTR
和 F_DEFERRED_ALL
不明确。 Technical Corrigendum f08/0001 更改了“12.4.3.4.5 对通用声明的限制”中的措辞,将“ 而不是 INTENT(IN) 属性”添加到
Two dummy arguments are distinguishable if
• one is a procedure and the other is a data object,
• they are both data objects or known to be functions, and neither is TKR compatible with the other,
• one has the ALLOCATABLE attribute and the other has the POINTER attribute and not the INTENT(IN) attribute, or
• one is a function with nonzero rank and the other is not known to be a function.
这是由于 POINTER、INTENT(IN) 虚拟变量的实参可以是指针或指针赋值语句中虚拟指针的有效目标(12.5.2.7 指针虚拟变量 J3/10-007r1). Links to the discussion and resolution 的问题。