私が取り組んでいるプロジェクトでは、新しいオブジェクトが作成され、古いオブジェクトが破棄されるときに、オブジェクトの配列のサイズを頻繁に変更する必要があることに気付きました。これは、コード全体で多数の異なる派生型で発生し、そのほとんどは相互に関係がありません。これらの配列のサイズを固有の派生型に合わせて変更するコードを書くのは面倒なので、派生型配列がそれらのサブルーチンを使用できるように、無制限のポリモーフィック仮引数を使用していくつかのヘルパー サブルーチンを作成してみようと考えました。
私が見つけたのは、私の無制限のポリモーフィック ルーチンをコンパイルして で呼び出すことができるということCLASS(*),INTENT(INOUT) :: val
です。この仮引数は、整数、割り当て可能な整数、または整数へのポインターを受け入れます。ALLOCATABLE
ただし、または属性を追加しようとするとすぐにPOINTER
、サブルーチンは正しくコンパイルされますが、コンパイラ エラーを取得せずに呼び出すことはできません。私の目標は派生型の配列のサイズを変更できるようにすることなので、これらの属性は、ルーチンが値を割り当て解除/割り当て/関連付けできるようにするために必要です。
実際に何もしようとせず、コンパイルに失敗するテスト コードを次に示します。このバージョンではスカラーの具象型を使用していますが、具象型の配列または派生型の配列を使用する元のコードでも同じエラーが発生します。
MODULE Resize_mod
PUBLIC
CONTAINS
SUBROUTINE resize(val)
CLASS(*),INTENT(INOUT) :: val
WRITE(*,*) 'resize'
ENDSUBROUTINE resize
SUBROUTINE resize_alloc(val)
CLASS(*),ALLOCATABLE,INTENT(INOUT) :: val
WRITE(*,*) 'resize_alloc'
ENDSUBROUTINE resize_alloc
SUBROUTINE resize_ptr(val)
CLASS(*),POINTER,INTENT(INOUT) :: val
WRITE(*,*) 'resize_ptr'
ENDSUBROUTINE resize_ptr
ENDMODULE Resize_mod
PROGRAM testResize
USE Resize_mod
INTEGER,TARGET :: array0d
INTEGER,ALLOCATABLE :: alloc0d
INTEGER,POINTER :: ptr0d
array0d=1
CALL resize(array0d)
ALLOCATE(alloc0d)
alloc0d=1
CALL resize(alloc0d)
!Following line gives: "Error: Actual argument to ‘val’ at (1) must be polymorphic"
CALL resize_alloc(alloc0d)
ALLOCATE(ptr0d)
ptr0d=1
CALL resize(ptr0d)
!Following line gives: "Error: Actual argument to ‘val’ at (1) must be polymorphic"
CALL resize_ptr(ptr0d)
ENDPROGRAM testResize
示されているように、コードは次のエラーを生成します。
testResize.f90:31:20:
CALL resize_alloc(alloc0d)
1
Error: Actual argument to ‘val’ at (1) must be polymorphic
testResize.f90:37:18:
CALL resize_ptr(ptr0d)
1
Error: Actual argument to ‘val’ at (1) must be polymorphic
エラーで指定された 2 行をコメント アウトすると、次の正しい出力が得られます。
resize
resize
resize
私は Fortran コードを広範囲に記述してきましたが、これまで無制限のポリモーフィズムを使用しようとしたことはありません。私がやろうとしていることが可能かどうか、もしそうなら、私が間違っていることを教えてください。
私は gfortran コンパイラ 5.4.0 を使用しています。これは、私が知る限り、無制限のポリモーフィズムを完全にサポートする必要があります。