fortran class declaration of dummy argument

醉酒当歌 提交于 2019-12-13 15:02:28

问题


I would like to have a derived type, a, which is empty. From this derived type I would like to define further types which extend a. Suppose all of these type extensions contain some generic procedure name, value, i.e value => valuea1, value => valuea2, etc.

If I then want to pass variables of class a to some other procedure, I need to declare the relevant dummy argument of that procedure with class(a). If I do this, however, then referencing the value of the dummy argument leads to compilation failure because the class a is actually empty - only the type extensions contain the procedure.

I could presumably get around this by having some procedure called value inside the type definition of a (then overriding in the extensions). However, given that I never want to declare any object with type a, this seems messy. It it possible to get around this?


回答1:


Yes, you can declare a type bound procedure even for an abstract type. It can be a real type bound procedure, or just an abstract interface.

type, abstract :: a
contains
  procedure :: valuea1, valuea2
  generic value :: value => valuea1, valuea2
end type


abstract interface
  ! the headers of valuea1, valuea2 here
  ! they should have a passed dummy argument class(a)
  ! and some other argument for the generic resolution
  ! for example:

  subroutine valua1(self, x)
    class(a), intent(in) :: self
    real, intent(inout) :: x
  end subroutine

  subroutine valua2(self, x)
    class(a), intent(in) :: self
    integer, intent(inout) :: x
  end subroutine

end interface

This way you cannot create variables of type(a), but you can make extended types which implement their own versions of value.




回答2:


Similar to the answer by @VladimirF, but taking your clarification that

I don't actually need the generic resolution; valuea1 and valuea2 accept the same type of arguments for the problem that I have in mind, I just want to bind to valuea1 in one type extension and valuea2 in another type extension.

Here, then, the base (abstract) type defines a deferred type-bound procedure value() with an interface taking class(a) as the passed argument. Other arguments can be added. Each extending type defines/overrides this type-bound procedure with its own procedure.

This means than in our final subroutine call test_sub the class(a) dummy argument does have a %value().

module types

! The base type
  type, abstract :: a
   contains
     procedure(value_if), deferred :: value
  end type a

! The interface for the type-bound procedures
  abstract interface
     subroutine value_if(var)
       import a
       class(a) var
     end subroutine value_if
  end interface

! The extending types, overriding the value subroutine

  type, extends(a) :: a1
   contains
     procedure :: value => value_a1
  end type a1

  type, extends(a) :: a2
   contains
     procedure :: value => value_a2
  end type a2

contains

  subroutine value_a1(var)
    class(a1) var
    print*, "Value of a1"
  end subroutine value_a1

  subroutine value_a2(var)
    class(a2) var
    print*, "Value of a2"
  end subroutine value_a2

end module types


program test

  use types

  type(a1) x
  type(a2) y

  call x%value
  call y%value

  call test_sub(x)
  call test_sub(y)

contains

  subroutine test_sub(var)
    class(a) var
    call var%value  ! This is defined
  end subroutine test_sub

end program test

This produces output

Value of a1
Value of a2
Value of a1
Value of a2



来源:https://stackoverflow.com/questions/22334675/fortran-class-declaration-of-dummy-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!