Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop Fortran 2003,选择类型以区分“实”和“实数组”_Oop_Polymorphism_Fortran - Fatal编程技术网

Oop Fortran 2003,选择类型以区分“实”和“实数组”

Oop Fortran 2003,选择类型以区分“实”和“实数组”,oop,polymorphism,fortran,Oop,Polymorphism,Fortran,我的问题是,可以使用select类型块来区分real::realInput和real::realArrayInput:?很清楚如何使用select类型来区分派生类型,但我不太清楚如何或是否可以在内部类型上使用它 在Mad Libs表格中,是否可以填写以下空白,以区分上述输入: select type (input) type is (real) print *, "I caught the realInput" type is (___________)

我的问题是,可以使用select类型块来区分real::realInput和real::realArrayInput:?很清楚如何使用select类型来区分派生类型,但我不太清楚如何或是否可以在内部类型上使用它

在Mad Libs表格中,是否可以填写以下空白,以区分上述输入:

select type (input)
    type is (real)
        print *, "I caught the realInput"
    type is (___________)
        print *, "I caught the realArrayInput"
end select
我发现一些相关的帖子没有包含我所希望的答案:

不可以。输入被声明为数组或标量,即使它是多态的,即使它是无限多态的

最近与CTS的进一步互操作性(可能是F201X的一部分)引入了假定秩和秩固有的概念,这可能会满足您的需要。但是,对于如何使用假定的秩对象,存在许多限制。而且不管选择类型如何,它仍然只对类型有效。select类型构造的语法根本不允许在类型保护语句中指定秩

显然,这取决于你真正想做什么。。。除了其他人提到的泛型接口之外,在当前Fortran中拥有可以是数组或标量的对象的一种方法还有其他可能性,那就是使用派生类型包装器,它是公共父类型的扩展。然后使用声明为父类型的多态对象,或者可以使用无限多态对象引用相关派生类型的对象

TYPE :: parent
END TYPE parent

TYPE, EXTENDS(parent) :: scalar_wrapper
  REAL :: scalar_component
END TYPE scalar_wrapper

TYPE, EXTENDS(parent) :: array_wrapper
  REAL :: array_component(10)
END TYPE array_wrapper
...

SUBROUTINE what_am_i(object)
  ! Note that object is scalar, but that doesn't tell us 
  ! the rank of the components of the dynamic type of object.
  CLASS(parent), INTENT(IN) :: object
  !****
  SELECT TYPE (object)
  TYPE IS (scalar_wrapper)
    PRINT "('I am a scalar with value ',G0)",  &
        object%scalar_component
  TYPE IS (array_wrapper)
    PRINT "('I am an array with values ',*(G0,:,','))",  &
        object%array_component
  CLASS DEFAULT
    PRINT "('I am not sure what I am.')"
  END SELECT
END SUBROUTINE what_am_i
结合M.S.B的评论并进行更详细的解释:您不能使用select type构造来区分实标量和实数组,因为它们只在维度上不同,而在类型上不同。当您声明变量输入时,您已经决定“永远”,它是否具有维度属性:

class(*) :: input_scalar
class(*), dimension(10) :: input_array
无论变量以后取哪个值,或者它指向哪个对象,如果它是指针,它都不能表示维度等级与其声明中的维度等级不同的东西

另一方面,例如,您可以使用接口构造或类型绑定过程中的泛型来区分相同类型但不同列组的对象。下面的示例演示了对于标量和秩1整数和实数数组

module testmod
  implicit none
  interface typetest
    module procedure typetest0, typetest1
  end interface typetest
contains
  subroutine typetest0(object)
    class(*), intent(in) :: object
    select type(object)
    type is (real)
      print *, "real scalar"
    type is (integer)
      print *, "integer scalar"
    end select
  end subroutine typetest0

  subroutine typetest1(object)
    class(*), dimension(:), intent(in) :: object
    select type(object)
    type is (real)
      print *, "real array"
    type is (integer)
      print *, "integer array"
    end select
  end subroutine typetest1
end module testmod

program test
  use testmod
  implicit none

  integer :: ii
  integer, dimension(10) :: iarray

  call typetest(ii)      ! invokes typetest0
  call typetest(iarray)  ! invokes typetest1

end program test

也许你可以通过将变量传递给一个基本过程,或者为两个过程编写一个通用接口来实现你的目标。你能用秩内在值检查秩吗?谢谢你。你能证实我理解你的意思吗?听起来type is real是有效的Fortran,但是select type块认为real::realInput和real::realArrayInput:都是真的,也就是说,两者都会导致上面我刚刚编辑的程序打印出来,我捕获了realInput。如果你不是这个意思,你能澄清一下吗?你的理解是正确的。选择类型仅对类型有效。