2015-10-06 55 views
1

How to pass subroutine names as arguments in Fortran classes?中,我們學習瞭如何將子例程名稱作爲參數傳遞給Fortran類。但是,我們如何從OUTSIDE類傳遞子例程名?在Fortran中從外部類傳遞子例程

隨後的代碼產生用於使用GNU的Fortran(GCC)5.1.0兩個不同的嘗試編譯錯誤:

gfortran -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5 casey.f08 
casey.f08:42:37: 

     call selector (ints % square, x , y) 
            1 
Error: Expected argument list at (1) 
casey.f08:43:24: 

     call selector (ints % double (x, y), x , y) 
         1 
Error: ‘double’ at (1) should be a FUNCTION 

的目標是,該例程selector採用不同的計算的路徑:一個方的數,另一個加倍。第一個編譯錯誤建議添加一個參數列表。天真的補救措施會產生第二個錯誤。

MWE如下。通過排列編程已經產生了許多變體;希望這個版本可以很容易地修復。

module myModule 

    implicit none 

    type  :: intermediates 
     real :: z 
    contains 
     private 
     procedure, nopass, public :: square => square_sub 
     procedure, nopass, public :: double => double_sub 
    end type intermediates 

    private :: square_sub 
    private :: double_sub 

contains 

    subroutine square_sub (x, y) 
     real, intent (in) :: x 
     real, intent (out) :: y 
      y = x ** 2 
    end subroutine square_sub 

    subroutine double_sub (x, y) 
     real, intent (in) :: x 
     real, intent (out) :: y 
      y = x * 2 
    end subroutine double_sub 

end module myModule 


program casey 

    use myModule 
    implicit none 

    real :: x = 10.0, y 
    type (intermediates) :: ints 
     call selector (ints % square, x , y) 
     call selector (ints % double (x, y), x , y) 

contains 

    subroutine selector (sub, x, y) 

     interface mySub 
      subroutine sub (x, y) 
       real, intent (in) :: x 
       real, intent (out) :: y 
      end subroutine sub 
     end interface mySub 

     real, intent (in) :: x 
     real, intent (out) :: y 

      call sub (x, y) 
      print *, 'x = ', x, ', y = ', y 

    end subroutine selector 

end program casey 
+0

我認爲應該有另一個問題指向你。相反在短期內,'ints%square'不是一個過程,而是一個綁定名稱。這可能足以讓你繼續搜索。 – francescalus

+1

閱讀http://stackoverflow.com/questions/11318816/passing-type-bound-procedures-as-arguments-in-fortran-90您可以參考行爲「內部」和「外部」的類別(稱爲Fortran中的派生類型) - Fortran中的派生類型在其中沒有可執行操作。類型具有綁定和過程指針組件,那些綁定和組件則指向始終在派生類型定義範圍之外的過程。 – IanH

回答

1

解決方法是將選擇器過程放在類中。在上面的示例中,subroutine selector位於program之內。在subroutine local_selector以下是procedure,其類型爲mySubs

module mySubs 

    implicit none 

    type :: myClass 
    contains 
     procedure, nopass, public :: square 
     procedure, nopass, public :: double 
     procedure, nopass, public :: local_selector 
    end type myClass 

contains 

    subroutine square (x, y) 
     real, intent (in) :: x 
     real, intent (out) :: y 
      y = x ** 2 
      print *, 'x = ', x, '; x ** 2 = ', y 
    end subroutine square 

    subroutine double (x, y) 
     real, intent (in) :: x 
     real, intent (out) :: y 
      y = x * 2 
      print *, 'x = ', x, '; 2 x = ', y 
    end subroutine double 

    subroutine local_selector (sub, x, y) 

     interface mySub 
      subroutine sub (x, y) 
       real, intent (in) :: x 
       real, intent (out) :: y 
      end subroutine sub 
     end interface mySub 

     real, intent (in) :: x 
     real, intent (out) :: y 

      call sub (x, y) 

    end subroutine local_selector 

end module mySubs 

program fixed 

    use mySubs 
    implicit none 

    real :: x = 10.0, y 

    type (myClass) :: thisClass 

     call thisClass % local_selector (square, x , y) 
     call thisClass % local_selector (double, x , y) 

end program fixed 
相關問題