3

Metcalfらによる「Fortran95/2003の説明」の例を取り上げます。これは、独自のコードが同じことを目的としているためです。

type, abstract :: my_numeric_type
contains
    private
    procedure(op2), deferred :: add
    generic, public :: operator(+) => add
end type

abstract interface
    function op2(a,b) result (r)
        import :: my_numeric_type
        class(my_numeric type), intent(in) :: a,b
        class(my_numeric type), allocatable :: r
    end function op2
end interface

type, extends(my_numeric_type) :: my_integer
    integer, private :: value
contains
    procedure :: add => add_my_integer
end type

さて、私の質問は、関数を適切に実装するにはどうすればよいかということですadd_my_integermy_integer型にバインドされたプロシージャであるため、最初の引数をキャストする必要があるようですが、2番目の引数my_numeric_typeは抽象インターフェイスに準拠している必要があります。結果は、に割り当てる必要rがありmy_integerますか?これが私がこれまでに思いついたもので、コンパイルされますが、タイプを常にチェックするのは奇妙に思え、セグメンテーション違反が発生します(おそらく私のコードの他の問題が原因です)。

function add_my_integer(a,b) result(r)
    class(my_integer), intent(in) :: a
    class(my_numeric_type), intent(in) :: b
    class(my_numeric_type), allocatable :: r

    allocate(my_integer :: r)
    select type (b)
        type is (my_integer)
            r = a+b
    end select
end function
4

1 に答える 1

5

これは私にとってはうまくいきますが、かなり複雑に見えます(多すぎますselect type)。簡単に出力できるように値を公開しました。それ以外の場合は、カスタムのゲッターとセッターが必要です。

module num

  type, abstract :: my_numeric_type
  contains
      private
      procedure(op2), deferred :: add
      generic, public :: operator(+) => add
      procedure(op), deferred :: ass
      generic, public :: assignment(=) => ass
  end type

  abstract interface
      subroutine op(a,b)
          import :: my_numeric_type
          class(my_numeric_type), intent(out) :: a
          class(my_numeric_type), intent(in) :: b
      end subroutine op
      function op2(a,b) result (r)
          import :: my_numeric_type
          class(my_numeric_type), intent(in) :: a,b
          class(my_numeric_type), allocatable :: r
      end function op2

  end interface

  type, extends(my_numeric_type) :: my_integer
      integer, public :: value
  contains
      procedure :: add => add_my_integer
      procedure :: ass => ass_my_integer
  end type

  contains

    function add_my_integer(a,b) result(r)
        class(my_integer), intent(in) :: a
        class(my_numeric_type), intent(in) :: b
        class(my_numeric_type), allocatable :: r

        select type (b)
            type is (my_integer)
                allocate(my_integer :: r)
                select type (r)
                  type is (my_integer)
                    r%value = a%value+b%value
                end select
        end select
    end function


    subroutine ass_my_integer(a,b)
        class(my_integer), intent(out) :: a
        class(my_numeric_type), intent(in) :: b

        select type (b)
            type is (my_integer)
                    a%value = b%value
        end select
    end subroutine

end module

program main
  use num

  class(my_integer), allocatable :: a, b, c
  allocate(my_integer :: a)
  allocate(my_integer :: b)
  allocate(my_integer :: c)
  a=my_integer(1)
  b=my_integer(2)
  c = a+b
  write (*,*) c%value
end program
于 2012-04-05T21:46:00.777 に答える