2015-09-29 75 views
1

How to pass subroutine names as arguments in Fortran?中,我們學習瞭如何在Fortran中傳遞子例程名稱作爲參數。我們如何在類結構中做到這一點?如何在Fortran類中將子例程名稱作爲參數傳遞

隨後的代碼產生使用GNU的Fortran(GCC)5.1.0以下編譯錯誤:

gfortran -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5 class_pass.f08 
myClass.f08:44:30: 

       class (test), target :: me 
           1 
Error: Derived type ‘test’ at (1) is being used before it is defined 
myClass.f08:9:21: 

      procedure, public :: action => action_sub 
        1 
Error: Non-polymorphic passed-object dummy argument of ‘action_sub’ at (1) 
myClass.f08:40:36: 

     class (test), target :: me 
            1 
Error: CLASS variable ‘me’ at (1) must be dummy, allocatable or pointer 
(null):0: confused by earlier errors, bailing out 

主程序如下。它包括用作診斷的例程check

include 'myClass.f08' 
program class_pass 

    use myClass 
    implicit none 

    type (test) :: myTest 

     call myTest % check() 
     call myTest % action (square_sub) 

end program class_pass 

模塊:

module myClass 

    implicit none 

    type  :: test 
     real :: x, y 
     contains 
      private 
      procedure, public :: action => action_sub 
      procedure, public :: square => square_sub 
      procedure, public :: double => double_sub 
      procedure, public :: check => check_sub 
    end type test 

    private :: action_sub 
    private :: square_sub 
    private :: double_sub 
    private :: check_sub 

contains 

    subroutine square_sub (me) 
     class (test), target :: me 
      me % y = me % x ** 2 
    end subroutine square_sub 

    subroutine double_sub (me) 
     class (test), target :: me 
      me % y = me % x * 2 
    end subroutine double_sub 

    subroutine check_sub (me) 
     class (test), target :: me 
      me % x = 5.0 
      call double_sub (me) 
      print *, 'x = ', me % x, ', y = ', me % y 
    end subroutine check_sub 

    subroutine action_sub (sub) 
     class (test), target :: me 

     interface mySub 
      subroutine sub (me) 
       class (test), target :: me 
      end subroutine sub 
     end interface mySub 

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

    end subroutine action_sub 

end module myClass 

非常感謝@Vladimir F到原來的解決方案和提示。

+0

接口塊是一個獨特的作用域單元,所以要'import'。 – francescalus

+2

可能的重複[如何聲明過程參數的接口部分,進而引用相同模塊的用戶派生類型?](http://stackoverflow.com/questions/8549415/how-to-declare -the-interface-section-for-a-procedure-argument-which-in-ref) – francescalus

+0

@francescalus一個非常有用的條目。謝謝。 – dantopa

回答

2

您的錯誤是由於您的程序中缺少參數action_sub和其他一些小事情。這個過程是通過

procedure, public :: action => action_sub 

,默認情況下多態類變量作爲第一個參數傳遞action_sub綁定到你的派生型。您已在其他類型的綁定過程中正確說明了這一點,但在此過程中沒有這樣做。您還需要在action_sub內的接口塊中導入派生類型,以便在那裏使用該類型。只是過程的此修改後的版本可以讓你的模塊正確編譯:

subroutine action_sub (me, sub) 
    class (test), target :: me 

    interface mySub 
     subroutine sub (me) 
      import test 
      class (test), target :: me 
     end subroutine sub 
    end interface mySub 

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

end subroutine action_sub 

接下來,在你的主程序,你這樣做:

call myTest % action (square_sub) 

爲了這裏引用square_sub你需要做出的程序在你的模塊中公開。一旦你從模塊程序刪除private屬性代碼編譯和運行:

x = 5.00000000  , y = 10.0000000 
x = 5.00000000  , y = 25.0000000 
+0

感謝您的編輯!關於如何使用該語言的非常好的解釋。 – dantopa

相關問題