带指针的 Fortran 赋值重载

Fortran assignment overload with pointers

我想重载要用于多态指针的类型的赋值。我不知道指针在运行时持有的实际子类型。 但是下面的示例代码重现了我得到的奇怪的编译器错误:

module example

type :: base_class
    real(4) :: some_garbage
contains

end type

type, extends(base_class) :: sub_class
    real(4) :: even_more_garbage
contains

end type

type :: main_operations_t
    class(base_class), pointer :: basic_pointer
    class(base_class), pointer :: pointer_array(:)
contains
    procedure :: main_operations
end type

interface assignment(=)
    module procedure assign_base_class
end interface

contains

subroutine assign_base_class(result_object, input_object)
implicit none
    class(base_class), pointer, intent(out) :: result_object
    class(base_class), pointer, intent(in) :: input_object
    result_object%some_garbage = input_object%some_garbage
end subroutine

subroutine main_operations(this)
implicit none
    class(main_operations_t) :: this
    class(base_class), pointer :: hack

    allocate(this%basic_pointer)
    allocate(this%pointer_array(2))

    this%basic_pointer%some_garbage = 0.0
    this%pointer_array(1)%some_garbage = 1.0
    this%pointer_array(2)%some_garbage = 2.0

    this%basic_pointer = this%pointer_array(1)
    this%pointer_array(1) = this%pointer_array(2)
    this%pointer_array(2) = this%basic_pointer

    this%basic_pointer = this%pointer_array(1)
    hack => this%pointer_array(1)
    hack = this%pointer_array(2)
    hack => this%pointer_array(2)
    hack = this%basic_pointer
end subroutine

end module

当我尝试分配给索引指针数组时,即

this%pointer_array(1) = this%pointer_array(2)
this%pointer_array(2) = this%basic_pointer

我在 Ubuntu 上使用 gfortran 4.8.4。 我收到编译器错误:

Error: Variable must not be polymorphic in intrinsic assignment at (1) - check that there is a matching specific subroutine for '=' operator

然而,分配给 0d 指针的工作没有任何抱怨。 带有 "hack" 指针的部分显示了一种可能的解决方法,以使其以丑陋的方式工作。

编译器抱怨它需要定义的赋值。你有一个,但它需要指点:

subroutine assign_base_class(result_object, input_object)
    class(base_class), pointer, intent(out) :: result_object
    class(base_class), pointer, intent(in) :: input_object

(没有必要在所有模块过程中重复 implicit none。我认为这是一种损害可读性的混乱。)

而且你的变量不是指针。 pointer_array(1) 不是指针,尽管 pointer_array 是指针。

一个解决方案是删除不需要的指针属性:

subroutine assign_base_class(result_object, input_object)
    class(base_class), intent(out) :: result_object
    class(base_class), intent(in) :: input_object
    result_object%some_garbage = input_object%some_garbage
end subroutine

编译干净。

如果您要进行指针赋值,那么在那里设置 pointer 属性是有意义的,但就目前而言,在定义的赋值中没有使用它。