Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Function Fortran和函数或子例程中的接口块_Function_Interface_Fortran_Overloading_Subroutine - Fatal编程技术网

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

Function Fortran和函数或子例程中的接口块,function,interface,fortran,overloading,subroutine,Function,Interface,Fortran,Overloading,Subroutine,我想写一个模块,它将根据“用户”在不同文件中提供的函数类型执行一些操作。此函数将作为该模块的“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) r

我想写一个模块,它将根据“用户”在不同文件中提供的函数类型执行一些操作。此函数将作为该模块的“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

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

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
我不建议这样做,但是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

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

您也可以将接口放在模块头中,并使用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

嗨,谢谢你的快速回复。带有可选参数的解决方案非常好,使用简单,易于实现,这就是我所需要的。谢谢!:)