如何在Fortran中为函数名设置别名

时间:2022-01-04 21:43:28

Not sure if the title is well put. Suggestions welcome.

不确定标题是否放好。建议欢迎。

Here's what I want to do. Check a condition, and then decide which function to use in a loop. For example:

这就是我想要做的。检查条件,然后确定在循环中使用哪个函数。例如:

if (a < 0) then
    loop_func = func1
else
    loop_func = func2
endif

I can then use loop_func as a pointer when writing my loop. Both functions take exactly the same inputs, and are different approaches on tackling the problem based on the value of a. This will allow me to only have one block of code, instead of two nearly identical blocks. This could apply to subroutines too.

然后我可以在编写循环时使用loop_func作为指针。这两个函数都采用完全相同的输入,并且是基于a的值来解决问题的不同方法。这将允许我只有一个代码块,而不是两个几乎相同的块。这也适用于子程序。

Any ideas how this might be implemented?

有什么想法可以实现吗?

Thank you.

谢谢。

2 个解决方案

#1


35  

Yes, Fortran has procedure pointers, so you can in effect alias a function name. Here is a code example which assigns to the function pointer "f_ptr" one function or the other. Thereafter the program can use "f_ptr" and the selected function will be invoked.

是的,Fortran有程序指针,所以你实际上可以别名一个函数名。这是一个代码示例,它为函数指针“f_ptr”分配一个函数或另一个函数。此后程序可以使用“f_ptr”并调用所选择的函数。

module ExampleFuncs

   implicit none

contains

function f1 (x)
  real :: f1
  real, intent (in) :: x

  f1 = 2.0 * x

  return
end function f1


function f2 (x)
   real :: f2
   real, intent (in) :: x

   f2 = 3.0 * x**2

   return
end function f2

end module ExampleFuncs


program test_func_ptrs

    use ExampleFuncs
    implicit none

   abstract interface
      function func (z)
         real :: func
         real, intent (in) :: z
      end function func
   end interface

   procedure (func), pointer :: f_ptr => null ()

   real :: input

   write (*, '( / "Input test value: ")', advance="no" )
   read (*, *) input

   if ( input < 0 ) then
      f_ptr => f1
   else
      f_ptr => f2
   end if

   write (*, '(/ "evaluate function: ", ES14.4 )' )  f_ptr (input)

   stop

end program test_func_ptrs

#2


2  

Most Fortran implementations do not have a standard way to manipulate function pointers or procedure pointers. However, Fortran 2003 and later have something. (See page 6 of this.)

大多数Fortran实现没有标准的方法来操作函数指针或过程指针。但是,Fortran 2003及更高版本有一些东西。 (见第6页。)

For the given situation, this will work pretty well in its place:

对于给定的情况,这将在它的位置很好地工作:

 function func1 (p1, p2, etc)
 ...  as you have it already
 end

 function func2 (p1, p2, etc)
 ...  as you have it already
 end

 function funcselect (a, p1, p2, etc)
     if (a < 0) then
          x = func1 (p1, p2, etc)
     else
          x = func2 (p1, p2, etc)
     endif
 end

Then just call funcselect with the extra parameter instead of what you would have done with loop_func.

然后使用额外的参数调用funcselect,而不是使用loop_func。

#1


35  

Yes, Fortran has procedure pointers, so you can in effect alias a function name. Here is a code example which assigns to the function pointer "f_ptr" one function or the other. Thereafter the program can use "f_ptr" and the selected function will be invoked.

是的,Fortran有程序指针,所以你实际上可以别名一个函数名。这是一个代码示例,它为函数指针“f_ptr”分配一个函数或另一个函数。此后程序可以使用“f_ptr”并调用所选择的函数。

module ExampleFuncs

   implicit none

contains

function f1 (x)
  real :: f1
  real, intent (in) :: x

  f1 = 2.0 * x

  return
end function f1


function f2 (x)
   real :: f2
   real, intent (in) :: x

   f2 = 3.0 * x**2

   return
end function f2

end module ExampleFuncs


program test_func_ptrs

    use ExampleFuncs
    implicit none

   abstract interface
      function func (z)
         real :: func
         real, intent (in) :: z
      end function func
   end interface

   procedure (func), pointer :: f_ptr => null ()

   real :: input

   write (*, '( / "Input test value: ")', advance="no" )
   read (*, *) input

   if ( input < 0 ) then
      f_ptr => f1
   else
      f_ptr => f2
   end if

   write (*, '(/ "evaluate function: ", ES14.4 )' )  f_ptr (input)

   stop

end program test_func_ptrs

#2


2  

Most Fortran implementations do not have a standard way to manipulate function pointers or procedure pointers. However, Fortran 2003 and later have something. (See page 6 of this.)

大多数Fortran实现没有标准的方法来操作函数指针或过程指针。但是,Fortran 2003及更高版本有一些东西。 (见第6页。)

For the given situation, this will work pretty well in its place:

对于给定的情况,这将在它的位置很好地工作:

 function func1 (p1, p2, etc)
 ...  as you have it already
 end

 function func2 (p1, p2, etc)
 ...  as you have it already
 end

 function funcselect (a, p1, p2, etc)
     if (a < 0) then
          x = func1 (p1, p2, etc)
     else
          x = func2 (p1, p2, etc)
     endif
 end

Then just call funcselect with the extra parameter instead of what you would have done with loop_func.

然后使用额外的参数调用funcselect,而不是使用loop_func。