如何为扩展抽象类型的派生类型重载运算符?

时间:2012-04-05 16:49:30

标签: fortran fortran2003

我以Metcalf等人的“Fortran 95/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_integer功能。似乎我被迫将第一个参数强制转换为my_integer,因为它是一个类型绑定过程,但第二个参数必须是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

1 个答案:

答案 0 :(得分:4)

这适合我,但它看起来很复杂(太多select type)。我将值设为public只是为了简单输出,否则你需要一个自定义的getter和setter。

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