fortran是否允许对函数的返回值进行内联操作



我正在尝试设计一个由对象组成的数据结构,这些对象包含另一种类型的对象作为实例变量。

我希望能够做这样的事情:

CALL type1_object%get_nested_type2_object()%some_type2_method()

请注意,我正在尝试立即使用getter get_nested_type2_object(),然后根据其返回值调用返回的type2对象中的方法。

目前,gfortran v4.8.2不接受这种语法,并认为get_nested_type2_object()是一个数组引用,而不是函数调用。有没有什么语法可以用来澄清这一点,或者标准不允许这样做?

为了给出一个更具体的例子,这里有一些代码来说明这一点:

家具_类别.F95:

MODULE furniture_class
   IMPLICIT NONE
   TYPE furniture_object
      INTEGER :: length
      INTEGER :: width
      INTEGER :: height
   CONTAINS
      PROCEDURE :: get_length
   END TYPE furniture_object
   CONTAINS
   FUNCTION get_length(self)
      IMPLICIT NONE
      CLASS(furniture_object) :: self
      INTEGER                 :: get_length
      get_length = self%length
   END FUNCTION
END MODULE furniture_class

现在,房间对象可能包含一个或多个家具对象。

房间类别.F95:

MODULE room_class
   USE furniture_class
   IMPLICIT NONE
   TYPE :: room_object
      CLASS(furniture_object), POINTER :: furniture
   CONTAINS
      PROCEDURE :: get_furniture
   END TYPE room_object
   CONTAINS
   FUNCTION get_furniture(self)
      USE furniture_class
      IMPLICIT NONE
      CLASS(room_object) :: self
      CLASS(furniture_object), POINTER :: get_furniture
      get_furniture => self%furniture
   END FUNCTION get_furniture
END MODULE room_class

最后,这里有一个程序,我试图访问房间内的家具对象(但编译器不允许):

房间测试F95

PROGRAM room_test
   USE room_class
   USE furniture_class
   IMPLICIT NONE
   CLASS(room_object), POINTER :: room_pointer
   CLASS(furniture_object), POINTER :: furniture_pointer
   ALLOCATE(room_pointer)
   ALLOCATE(furniture_pointer)
   room_pointer%furniture => furniture_pointer
   furniture_pointer%length = 10
   ! WRITE(*,*) 'The length of furniture in the room is', room_pointer%furniture%get_length() - This works.
   WRITE(*,*) 'The length of furniture in the room is', room_pointer%get_furniture()%get_length() ! This line fails to compile
   END PROGRAM room_test

如果我不使用getter返回嵌套对象,我当然可以直接访问家具对象,但这会破坏封装,并可能在生产代码中出现问题,而生产代码比我在这里展示的要复杂得多。

我想要做的是Fortran标准不支持,还是只需要一个更兼容的编译器?

标准语言的语法不支持您想要做的事情。

(可能适用于"取消引用"函数结果的一般语法(不一定是这种特定情况)的变体可能是不明确的——考虑子字符串、整个数组引用、数组节等。)

通常,您将第一个函数调用的结果分配给适当类型的[pointer]变量,然后将第二个函数的绑定应用于该变量。

或者,如果要将运算应用于表达式中的主函数(如函数引用)以提供另一个值,则可以使用运算符。

一些可能相当主观的评论:

  • 房间对象实际上并不包含家具对象,而是包含对家具对象的引用。也许您使用该引用的方式暗示了"包含"它的父对象,但这不是组件定义自然建议的。

    (使用指针组件表明您希望房间指向(即参考)某些家具。就语言而言,指针组件引用的对象通常不被视为组件父对象值的一部分-考虑内部赋值的工作方式、修改INTENT(In)参数的限制等。

    一个非指针组件向我表明家具是房间的一部分。在Fortran语言的意义上,对象是一个非指针组件,它始终是组件父对象值的一部分。

    突出显示不同房间中的指针组件可能指向同一件家具;无指针家具对象只能直接作为一个房间的一部分。)

  • 使用带有指针结果的函数时需要非常小心。在一般情况下,是不是:

    p = some_ptr_function(args)
    

    (也许我不小心泄露了内存)或

    p => some_ptr_function(args)
    

    只有一点字符差异,两种语法都有效,语义完全不同。如果第二种情况是预期的,那么为什么不通过子例程参数将指针传回来呢?打字上的一个无关紧要的区别,它更安全。

一个适用于上述某些情况的一般提醒——在表达式的上下文中,对函数引用的求值会产生一个值。值不是变量,因此不允许更改[修改]它们。

最新更新