Fortran 90 中的可选子例程

发布于 2024-10-18 02:01:42 字数 1277 浏览 3 评论 0原文

我怎样才能在 fortran 90 中实现这个目标?我有一个接受函数的例程

subroutine foo(bar, mysub)
   integer, intent(in) :: bar
   interface
      subroutine mysub(x)
         integer :: x
      end subroutine
   end interface

   call mysub(bar)

end subroutine

现在我希望该例程是可选的

subroutine foo(bar, mysub)
   integer, intent(in) :: bar
   interface
      subroutine mysub(x)
         integer :: x
      end subroutine
   end interface
   optional :: mysub

   call mysub(bar)

end subroutine

现在,如果 mysub 是一个标准变量 var 我可以做类似的事情,

 if (present(var)) then
     l_var = var
 else
     l_var = <default value>
 endif

但据我所知,我不能对可选子程序。实际上这是不可能的

subroutine foo(bar, mysub)
   integer, intent(in) :: bar
   interface
      subroutine mysub(x)
         integer :: x
      end subroutine
   end interface
   optional :: mysub

   if (present(mysub)) then
       l_mysub = mysub
   else
       l_mysub = default
   endif

   call mysub(bar)

end subroutine

,因为您无法声明 l_mysub。有可能通过一些我不知道的技巧吗?是的,我当然可以

   if (present(mysub)) then
       call mysub(bar)
   else
       call default(bar)
   endif

,但我的情况更复杂,我必须把这张支票到处放。考虑一下我可以通过三个可选子例程。

How can I achieve this objective in fortran 90 ? I have a routine accepting a function

subroutine foo(bar, mysub)
   integer, intent(in) :: bar
   interface
      subroutine mysub(x)
         integer :: x
      end subroutine
   end interface

   call mysub(bar)

end subroutine

Now I want the routine to be optional

subroutine foo(bar, mysub)
   integer, intent(in) :: bar
   interface
      subroutine mysub(x)
         integer :: x
      end subroutine
   end interface
   optional :: mysub

   call mysub(bar)

end subroutine

Now, if mysub were a standard variable var I could do something like

 if (present(var)) then
     l_var = var
 else
     l_var = <default value>
 endif

but as far as I know, I cannot perform the same for an optional subroutine. In practice this is not possible

subroutine foo(bar, mysub)
   integer, intent(in) :: bar
   interface
      subroutine mysub(x)
         integer :: x
      end subroutine
   end interface
   optional :: mysub

   if (present(mysub)) then
       l_mysub = mysub
   else
       l_mysub = default
   endif

   call mysub(bar)

end subroutine

because you cannot declare l_mysub. Is it possible through some trick I am not aware of ? Yes, of course I can do

   if (present(mysub)) then
       call mysub(bar)
   else
       call default(bar)
   endif

but my case is more complex and I would have to put this check everywhere. Consider that I have three optional subroutines I may pass.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉城 2024-10-25 02:01:42

我的第一个想法是使用过程指针,但后来我注意到您指定了 fortran 90,所以这不是一个选项。
如何为原始的 foo 创建一个包装子例程,如果指定了给定的子例程,则使用它来调用它,否则使用 default 来调用它?像这样的东西(未经测试):

subroutine foo_wrap(bar, mysub)
  integer, intent(in) :: bar
  interface
    subroutine mysub(x)
      integer :: x
    end subroutine mysub
  end interface
  optional :: mysub

  if (present(mysub)) then
    call foo(bar, mysub)
  else
    call foo(bar, default)
  endif
end subroutine foo_wrap  

我认为,使用多个可选子例程可能会变得有点复杂,但并非不可能。

My first thought was to use a procedure pointer, but then I noticed you specified fortran 90, so that's not an option.
How about making a wrapper subroutine for your original foo, which calls it with the given subroutine if it is specified, or else with default? Something like this (untested):

subroutine foo_wrap(bar, mysub)
  integer, intent(in) :: bar
  interface
    subroutine mysub(x)
      integer :: x
    end subroutine mysub
  end interface
  optional :: mysub

  if (present(mysub)) then
    call foo(bar, mysub)
  else
    call foo(bar, default)
  endif
end subroutine foo_wrap  

With multiple optional subroutines it might become a little complex, but not impossible, I think.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文