通过 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"。

  1. 这 "solution" 是否以某种方式被弃用、劝阻、危险或其他?我问这个是因为我真的没怎么用过 POINTERs。

此外,我定义了一个pntr函数,它returns一个POINTER到它的唯一(非ALLOCATABLE数组或数组的一部分)INput 参数,这样我就可以使用它 "in-line" 而无需在主程序中定义 POINTER 并且我不必将 TARGET 属性放在实际参数上。

  1. 是否可以通过使用 pntr 创建一个临时数组?我想是的,但我不确定在主程序中定义 POINTER 并将其关联是否会在这方面产生影响。
  2. 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_PTRF_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 的问题。