2017-06-13 16 views
1

多型ポインタに使用するタイプの割り当てをオーバーロードします。私はポインタが実行時に保持している実際のサブタイプを知らない。私はUbuntuの上でのgfortran 4.8.4を使用ポインタを使用したFortran割り当てのオーバーロード

this%pointer_array(1) = this%pointer_array(2) 
this%pointer_array(2) = this%basic_pointer 

すなわちインデックス付きのポインタ配列に代入しようとすると

module example 

type :: base_class 
    real(4) :: some_garbage 
contains 

end type 

type, extends(base_class) :: sub_class 
    real(4) :: even_more_garbage 
contains 

end type 

type :: main_operations_t 
    class(base_class), pointer :: basic_pointer 
    class(base_class), pointer :: pointer_array(:) 
contains 
    procedure :: main_operations 
end type 

interface assignment(=) 
    module procedure assign_base_class 
end interface 

contains 

subroutine assign_base_class(result_object, input_object) 
implicit none 
    class(base_class), pointer, intent(out) :: result_object 
    class(base_class), pointer, intent(in) :: input_object 
    result_object%some_garbage = input_object%some_garbage 
end subroutine 

subroutine main_operations(this) 
implicit none 
    class(main_operations_t) :: this 
    class(base_class), pointer :: hack 

    allocate(this%basic_pointer) 
    allocate(this%pointer_array(2)) 

    this%basic_pointer%some_garbage = 0.0 
    this%pointer_array(1)%some_garbage = 1.0 
    this%pointer_array(2)%some_garbage = 2.0 

    this%basic_pointer = this%pointer_array(1) 
    this%pointer_array(1) = this%pointer_array(2) 
    this%pointer_array(2) = this%basic_pointer 

    this%basic_pointer = this%pointer_array(1) 
    hack => this%pointer_array(1) 
    hack = this%pointer_array(2) 
    hack => this%pointer_array(2) 
    hack = this%basic_pointer 
end subroutine 

end module 

: しかし、次のコード例は、私が得る奇妙なコンパイラエラーを再現します。 は、私は、コンパイラのエラーを取得する:0Dポインタに

Error: Variable must not be polymorphic in intrinsic assignment at (1) - check that there is a matching specific subroutine for '=' operator

割り当ては、しかし、苦情なしで動作します。 「ハック」ポインタが表示されているセクションでは、これを醜い方法で動作させるための回避策が示されています。

答えて

0

コンパイラは、定義済みの割り当てが必要であると不平を言っています。あなたは1を持っているが、それは、ポインタを必要とします。

subroutine assign_base_class(result_object, input_object) 
    class(base_class), pointer, intent(out) :: result_object 
    class(base_class), pointer, intent(in) :: input_object 

(すべてのモジュール手続きでimplicit noneを繰り返す必要はない、私はそれが可読性に害を与える乱雑であると主張したい。。)

そして、あなたの変数ポインタではありません。 pointer_arrayがポインタであっても、pointer_array(1)はポインタではありません。

ソリューションは、不要なポインタ属性を削除することです:

subroutine assign_base_class(result_object, input_object) 
    class(base_class), intent(out) :: result_object 
    class(base_class), intent(in) :: input_object 
    result_object%some_garbage = input_object%some_garbage 
end subroutine 

これはきれいにコンパイルされます。

ポインタの割り当てを行っている場合はpointer属性を持つのが理にかなっていますが、定義されている割り当てでは使用されません。

関連する問題