0

Fortran2003 で連結リスト構造を書いています。このリンクされたリストのノードには、交互に 2 つの種類があります。リストはエッジのトポロジー リングを表し、各エッジは 2 つの頂点で囲まれ、各頂点は 2 つのエッジに接続されます。これらの構造体は抽象 NODE_T 型として宣言され、VN_T と EN_T の 2 つのサブクラスによって実装されます。VN_T は 2 つの EN_T を指し、その逆も同様です。リストはタイプ間で交互になるため、ポインターはサブクラスに格納されます。私の問題は、NEXT() および PREV() と呼ばれる VN_T および EN_T に型バインド関数 (メソッド?) を追加することであり、ポリモーフィズムを介して正しいことを行います。VN_T%NEXT() は2 つのステップでスキップし、次の VN_T を取得する必要があります (最初の VN_T とは EN_T で区切られています)。

私のタイプ/クラスの定義は次のとおりです。

TYPE, ABSTRACT :: NODE_T
  INTEGER :: IENT
  INTEGER :: ISIDE
  INTEGER :: ISUBTYPE
  INTEGER :: IPAD
CONTAINS
  PROCEDURE(NEXTA), DEFERRED :: NEXT
  PROCEDURE(PREVA), DEFERRED :: PREV
  END TYPE NODE_T

ABSTRACT INTERFACE
FUNCTION NEXTA(PENT)
IMPORT NODE_T
CLASS(NODE_T), POINTER :: NEXTA
CLASS(NODE_T) :: PENT
END FUNCTION

FUNCTION PREVA(PENT)
IMPORT NODE_T
CLASS(NODE_T), POINTER :: PREVA
CLASS(NODE_T) :: PENT
END FUNCTION
END INTERFACE

  TYPE, EXTENDS(NODE_T) :: VN_T
     DOUBLE PRECISION DT
     CLASS(EN_T), POINTER :: N
     CLASS(EN_T), POINTER :: P
     CONTAINS
      PROCEDURE :: NEXT => NEXTV
      PROCEDURE :: PREV => PREVV
  END TYPE

  TYPE, EXTENDS(NODE_T) :: EN_T
     CLASS(VN_T), POINTER :: N
     CLASS(VN_T), POINTER :: P
     CONTAINS
      PROCEDURE :: NEXT => NEXTE
      PROCEDURE :: PREV => PREVE
  END TYPE

next/prev ルーチンの実装はすべてほぼ同じで、next/prev と EN/VN の 4 つの組み合わせがあります。

FUNCTION NEXTE(PENT)
CLASS(NODE_T), POINTER :: NEXTE
CLASS(EN_T) PENT
NEXTE => PENT%N%N
END FUNCTION

これらの関数を呼び出すと:

CLASS(NODE_T), POINTER :: NODE1, NODE2
NODE2 => NODE1%NEXT()

次に、私のコンパイラ (Intel FORTRAN XE Composer 2011、つまり v12.0) が次のメッセージを表示します。

error #8314: If the rightmost part-name is of abstract type, data-ref shall be polymorphic   [NEXT]
            NODE2 => NODE1%NEXT()
---------------------------^

これに基づいて、このドキュメントは、サブクラスの実装の1つを選択するのではなく、基本クラスでプロシージャNEXTを呼び出そうとしていることを示しているようです(右側にあるNODE1の具体的なタイプに基づいて実行できるはずです)手元ですよね?)。

私は F2003 の OOP 機能に慣れていないので、Java でこのパターンのモックアップを作成し、満足のいく作業ができました。これが a) F2003 の OOP 動作の違いなのか、2) コンパイラのバグなのか、3) 頭がおかしいだけなのか、誰でも明らかにできますか...

4

1 に答える 1

1

コンパイラを更新する必要がある場合があります。このスレッドで議論されているように

http://software.intel.com/en-us/forums/showthread.php?t=78855

Fortran 標準では、本来、抽象型の型束縛手続きを直接呼び出すことは許可されていませんでした。ただし、標準が変更され、今では Intel Fortran になっているはずです。

別の方法は、基本クラスを次のように変更することです。

TYPE :: NODE_T
  INTEGER :: IENT
  INTEGER :: ISIDE
  INTEGER :: ISUBTYPE
  INTEGER :: IPAD
CONTAINS
  PROCEDURE :: NEXT
  PROCEDURE :: PREV
  END TYPE NODE_T
于 2012-04-25T23:26:19.600 に答える