我正在尝试使用过程指针(Fortran 2003中的新功能)指向元素函数,但它不起作用。我真的需要函数ELEMENTAL
并需要指向它的指针。在Fortran中指向元素函数真的不可能吗?
module elemfunc
implicit none
contains
elemental function fun111(x) result(y)
real*8, intent(in) :: x
real*8 :: y
y = x**2+1
end function fun111
end module elemfunc
program testptr
use elemfunc
implicit none
interface
elemental function func (z)
real*8 :: func
real*8, intent (in) :: z
end function func
end interface
procedure (func), pointer :: ptr
ptr => fun111
print *, ptr( (/1.0d0,2.0d0/) )
end program testptr
错误讯息:
main.f90:12.7:ptr=>fun111
1
Nonintrinstic elemental procedure pointer 'func111' is invalid in procedure pointer assignment at (1)
答案 0 :(得分:3)
在2003年fortran标准的第7.4.2 Pointer Assignment
段中,明确规定不允许这样做:
C728 (R742) The proc-target shall not be a nonintrinsic elemental procedure
(这个约束仍然存在于fortran 2008标准中,所以它没有放松。)
答案 1 :(得分:2)
我有这个完全相同的问题,甚至没有意识到这是一个问题,直到我用gfortran编译。不幸的是,也禁止对元素过程使用伪过程参数。但是,它仍然可以实现您想要的功能,尽管它有点笨拙。
你可以合法地做的是使用元素函数调用纯函数。根据您的需要,元素函数可以是类型绑定的。
将过程指针和函数放在模块中:
module A
implicit none
procedure(func_IF), pointer :: ptr => null()
abstract interface
pure function func_IF(x)
real, intent(in) :: x
real :: func_IF
end function
end interface
contains
! Non type bound elemental
elemental function myfun1(x) result(r)
real, intent(in) :: x
real :: r
if(associated(ptr)) r = ptr(x)
end function
end module
将指针和函数放在派生类型中:
module B
implicit none
type :: foo
procedure(func_IF), nopass, pointer :: ptr => null()
contains
procedure, pass :: myfun2
end type
abstract interface
pure function func_IF(x)
real, intent(in) :: x
real :: func_IF
end function
end interface
contains
! Type bound elemental
elemental function myfun2(this, x) result(r)
class(foo), intent(in) :: this
real, intent(in) :: x
real :: r
if(associated(this%ptr)) r = this%ptr(x)
end function
end module
小型测试程序:
program main
use A
use B
implicit none
type(foo) :: myfoo
myfoo%ptr => bar
ptr => bar
print*, myfun1([10., 20.])
print*, myfoo%myfun2([10., 20.])
contains
! Demo pure function with interface func_IF
pure function bar(x)
real, intent(in) :: x
real :: bar
bar = x**2
end function
end