带指针的 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
属性是有意义的,但就目前而言,在定义的赋值中没有使用它。
我想重载要用于多态指针的类型的赋值。我不知道指针在运行时持有的实际子类型。 但是下面的示例代码重现了我得到的奇怪的编译器错误:
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
属性是有意义的,但就目前而言,在定义的赋值中没有使用它。