函数或子例程中的Fortran和接口块

时间:2015-10-11 22:22:37

标签: function interface fortran overloading subroutine

我想编写一个模块,它将根据“user”在不同文件中提供的功能类型执行一些操作。该函数将作为该模块的“execute(...)”子例程的参数传递。这基本上就是我想要获得的,但我不知道这是否可行,我该怎么做才能正确。

module mod1
contains
subroutine execute(func)
 interface func
 real function func1(a,b)
    real a,b
 end function 
 real function func2(a,b,c)
    real a,b,c
 end function 
 ! more similar functions here
 end interface func

   ! -------------------
   ! here some how choose between func1 or func2
   ! and do the calculations
   if(func1) then ...
   else if(func2) ...
   ! -------------------
endsubroutine execute 
endmodule mod1
------------------------------------------
program
use mod1
call execute(test) 
contains
real function test(a,b)
real a,b
test = a + b
end function
end program

我知道这段代码不会编译,但这只是草图的样子。对于我来说,对于这个问题唯一丑陋的解决方案是为执行子程序编写许多替代方法,即execute_1,execute_2,并且根据测试功能,用户必须选择正确的execute_X函数。

对于这个问题有没有更好的解决方案?

提前致谢。 KK

2 个答案:

答案 0 :(得分:2)

您也可以将接口放在模块头中,并像这样使用func1和func2的过程属性。如果你想在别处使用它们,这很有用,因为你只是在一个地方定义它们。

module mod1

abstract interface
  real function f1(a,b)
    real,intent(in) :: a,b
  end function f1
  real function f2(a,b,c)
    real,intent(in) :: a,b,c
  end function f2  
end interface

contains

  subroutine execute(func1, func2)
  procedure(f1),optional :: func1
  procedure(f2),optional :: func2

  !...

  if (present(func1)) x = func1(a, b)
  if (present(func2)) x = func2(a, b, c)
  end subroutine execute

end module mod1

答案 1 :(得分:1)

根据示例源猜测一下您的意图,您的问题是您需要一个可能在其特征上有所不同的虚拟过程 - 例如参数的数量。

我不推荐这个,但Fortran允许虚拟过程有一个隐式接口 - 你可以给func虚拟过程外部属性,然后它在程序员的头上,以确保通过虚拟过程的引用的性质与实际过程的接口一致。需要显式接口的语言工具可能不适用于此方法。

subroutine execute(func)
  real, external :: func
  !...
  if (some_condition) then
    x = func(a, b)
  else
    x = func(a, b, c)
  end if

如果您希望虚拟过程具有显式接口,那么您可以使用可选参数。

module mod1
contains
  subroutine execute(func1, func2)
    interface
      real function func1(a,b)
        real a,b
      end function func1
      real function func2(a,b,c)
        real a,b,c
      end function func2
    end interface
    optional :: func1, func2

    !...

    if (present(func1)) x = func1(a, b)
    if (present(func2)) x = func2(a, b, c)
  end subroutine execute
end module mod1

program p
  use mod1
  call execute(func1=test) 
contains
  real function test(a,b)
    real a,b
    test = a + b
  end function
end program p

此问题的更一般解决方案可以通过绑定派生类型来调用过程 - 过程的调用始终使用相同的接口,但是可以使用派生类型的组件将附加信息传递给过程。