可区分指针的通用名称

Generic name for distinguishable pointers

是否可以为两个不同类型的指针使用相同的通用名称?下面当然不行,但应该能说明我的意思:

real(4), pointer :: s_p
real(8), pointer :: d_p
generic :: p => s_p,d_p

对于过程,这些事情可以通过将可识别过程定义为 module procedure 的接口来完成,对于类型绑定过程,存在类似于给定示例使用的 generic 类型。所以我想知道指针是否也存在这样的东西。

我想提一下无限多态指针 (class(*)) 可能不是我想要的,因为我试图将现有的库泛化为双精度输入,因此我有一个实现 select type 块比在各处定义两个指针要多得多。

编辑:

当然可以将同一个指针关联到不同type/kind的变量。举几个例子:

program test

   implicit none
   real(4),target :: a
   real(8),target :: b
   class(*),pointer :: p

   a=2e0
   b=3d0

   p=>a
   call printer(p)
   a=a+4e0
   call printer(p)
   p=>b
   call printer(p)

   associate (u=>a)       ! for me it's still a miracle why this even works
      print*,u
      a=a+3e0
      print*,u
   end associate
   associate (u=>b)
      print*,u
   end associate

contains

   subroutine printer(p)

      class(*),pointer :: p

      select type (p) 
      type is (real(4))
         p=p+2d0              ! even the wrong 2d0 gets converted correctly
         print*,p
      type is (real(8))
         print*,p
      end select

   end subroutine

end program

我对这个解决方案的问题是我必须在使用指针的库中的任何地方实现 select type 块。 (目前我只知道很多地方。)

所以主要问题是无限多态指针(示例中的 p)保持多态,除非它在 ​​select type 环境中使用。这当然是必要的,因为指针可以是一切。所以实际的问题是:是否有可能提前告诉多态指针:你只能是这个或那个(例如 real(4) 或 real(8))并且取决于它关联的是什么,它知道什么是吗?

答案可能是否定的,但目前我还没有真正看到编译器在哪种情况下可能无法区分 types/kinds。

不,这是不可能的。 Fortran 2008 标准中的条款 C714 (R733) 规定:

If data-target is not unlimited polymorphic, data-pointer-object shall be type compatible (4.3.1.3) with it and the corresponding kind type parameters shall be equal.

但是,您可以将相应的代码放在它自己的文件中,并将其包含在不同类型的变量中:

common.inc.F90:

real(KINDVAR), pointer :: p

contains

function fun1(x) result(res)
  real(KINDVAR) :: x, res
  ! ...
end function

module_double.F90:

module test_double
  use,intrinsic :: ISO_Fortran_env, only: REAL64
  integer,parameter :: KINDVAR = REAL64

  include 'common.inc.F90'
end module

module_single.F90:

module test_single
  use,intrinsic :: ISO_Fortran_env, only: REAL32
  integer,parameter :: KINDVAR = REAL32

  include 'common.inc.F90'
end module

然后您可以包含不同的模块,甚至可以即时重命名子例程:

use test_single only: fun1_sgl => fun1, p_sgl => p
use test_double only: fun1_dbl => fun1, p_dbl => p

这叫做 "Poor man's templates" 并已发布 here

没有。数据指针是一个变量。您不能在同一范围内访问具有相同名称的两个不同变量。

如果您假设可以...在许多情况下,编译器将无法知道当出现该通用名称时您指的是哪个变量。

通用过程名称的情况不同 - 当引用通用过程名称时,编译器可以通过检查过程引用中参数的数量、类型、种类和等级来确定哪个特定过程是相关的。语言规则确保最多只能有一个这样的匹配特定过程,并且通用过程名称不会出现在无法解析相关特定过程的上下文中。