过程指针不能指向元素函数
Posted
技术标签:
【中文标题】过程指针不能指向元素函数【英文标题】:Elemental functions cannot be pointed to by procedure pointers 【发布时间】:2013-02-19 22:12:24 【问题描述】:我正在尝试使用过程指针(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)
【问题讨论】:
FWIW 你的代码对我来说编译和执行(显然)正确。我正在使用英特尔 Fortran 13.1.0.149。即使我将警告和语法检查提高到 11 次,编译器也不会发出任何抱怨。我不能说我确定您的代码符合标准,但我看不出它也不符合标准。 太棒了!我正在使用 gfortran 4.7(不确定...)。也许我应该更新我的 gfortran ??? @High Performance Mark 见NewFeatureFortran2003, seach 'elemental', 第一个匹配结果说 elemental INTERFACE is not allowed, 但不知道是不是和elemental FUNCTIONS一样...跨度> 最新的 gfortran 4.8 产生相同的结果。 【参考方案1】:我遇到了同样的问题,直到我用 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
【讨论】:
【参考方案2】:在 fortran 2003 标准的 7.4.2 Pointer Assignment
段中明确指出这是不允许的:
C728 (R742) The proc-target shall not be a nonintrinsic elemental procedure
(这个约束在fortran 2008标准中仍然存在,所以没有放宽。)
【讨论】:
是的,这与 OP 在他的评论中引用的约束相同。 @VladimirF:啊,我没看过那个。所以看来 OP 已经知道他的问题的答案了。 谢谢大家。约束真的让我很难过...!_!....我必须在不使用元素函数的情况下再次重写我的代码以上是关于过程指针不能指向元素函数的主要内容,如果未能解决你的问题,请参考以下文章