在类型绑定的基本过程中将对象作为 intent(inout) 传递
Passed object as intent(inout) in a type-bound elemental procedure
我想将文本添加到标量对象的组件中,无论此附加文本的形状如何。
为了尝试这个,我创建了一个基本过程,它有一个基本输入参数,但只有一个 intent(inout)
参数,即传递的对象。
这是一个 MWE:
module add_mod
implicit none
type obj_A
character(len=:), allocatable :: Message
contains
procedure, pass(objA) :: add
procedure, pass(objA) :: write
end type
contains
elemental subroutine add( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*), intent(in) :: text
objA%Message=objA%Message//text
end subroutine add
impure elemental subroutine write( objA, text )
implicit none
class(obj_A), intent(in) :: objA
character(len=*), intent(in) :: text
print*,'write ', text
end subroutine write
end module
program test
use add_mod
implicit none
type(obj_A) :: testA
call testA%add('toto')
print *, testA%Message
! call testA%add( ['toto','abcc','d,ef'] )
print *, testA%Message
call testA%write( ['toto','abcc','d,ef'] )
end program
如果我对 call testA%add( ['toto','abcc','d,ef'] )
行进行注释,它就可以正常工作。但是如果我取消注释,我在编译过程中会出错
Error: Actual argument at (1) for INTENT(INOUT) dummy 'objA' of ELEMENTAL subroutine 'add' is a scalar, but another actual argument is an array`
我明白为什么用testA%write
调用是正确的,这是由于传递对象的intent(in)
;在这种情况下,编译器理解一个参数是标量形状,另一个是数组形状。
对于 testA%add( ['toto','abcc','d,ef'] )
,我还了解到它需要一个形状为 obj_A
的数组作为 intent(inout)
,因为为输入提供的文本是一个标量。因此,这不是正确的方法。
无论文本的形状如何,是否有将文本添加到 obj_A%Message
的正确方法?
使用 elemental
子例程时,您可以提供一个数组输入和一个 array 输出 [然后以元素方式进行操作]。但是,您正在尝试将数组输入分配给标量输出(此处:testA
)。
如果您使用大小为 3 的数组输出,您的例程将按预期工作:
module add_mod
implicit none
type obj_A
character(len=:), allocatable :: Message
contains
procedure, pass(objA) :: add
end type
contains
elemental subroutine add( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*),intent(in) :: text
objA%Message=objA%Message//text
end subroutine add
end module
program test
use add_mod
implicit none
type(obj_A) :: testA
type(obj_A) :: testB(3)
call testA%add('toto')
print *, testA%Message
call testB%add( ['toto','abcc','d,ef'] )
print *, testA%Message
print *, testB(1)%Message, testB(2)%Message, testB(3)%Message
end program
这是一个将字符串数组添加到标量输出的版本。请注意,由于这个星座,子程序不能是elemental
。但是,它可以是 pure
:
module add_mod
implicit none
type obj_A
character(len=:), allocatable :: Message
contains
procedure, pass(objA) :: add
end type
contains
pure subroutine add( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*), dimension(:), intent(in) :: text
integer :: i
do i=1,size(text)
objA%Message=objA%Message//text(i)
enddo !i
end subroutine add
end module
program test
use add_mod
implicit none
type(obj_A) :: testA
call testA%add(['toto'])
print *, testA%Message
call testA%add( ['toto','abcc','d,ef'] )
print *, testA%Message
end program
最后,要同时支持标量和数组参数,您需要提供并绑定多个实现,然后使用 generic
接口以相同的名称提供它们:
module add_mod
implicit none
type obj_A
character(len=:), allocatable :: Message
contains
generic :: add => add1, add2
procedure, pass(objA) :: add1
procedure, pass(objA) :: add2
end type
contains
pure subroutine add1( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*), dimension(:), intent(in) :: text
integer :: i
do i=1,size(text)
objA%Message=objA%Message//text(i)
enddo
end subroutine add1
pure subroutine add2( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*), intent(in) :: text
objA%Message=objA%Message//text
end subroutine add2
end module
program test
use add_mod
implicit none
type(obj_A) :: testA
call testA%add('toto')
print *, testA%Message
call testA%add( ['toto','abcc','d,ef'] )
print *, testA%Message
end program
我想将文本添加到标量对象的组件中,无论此附加文本的形状如何。
为了尝试这个,我创建了一个基本过程,它有一个基本输入参数,但只有一个 intent(inout)
参数,即传递的对象。
这是一个 MWE:
module add_mod
implicit none
type obj_A
character(len=:), allocatable :: Message
contains
procedure, pass(objA) :: add
procedure, pass(objA) :: write
end type
contains
elemental subroutine add( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*), intent(in) :: text
objA%Message=objA%Message//text
end subroutine add
impure elemental subroutine write( objA, text )
implicit none
class(obj_A), intent(in) :: objA
character(len=*), intent(in) :: text
print*,'write ', text
end subroutine write
end module
program test
use add_mod
implicit none
type(obj_A) :: testA
call testA%add('toto')
print *, testA%Message
! call testA%add( ['toto','abcc','d,ef'] )
print *, testA%Message
call testA%write( ['toto','abcc','d,ef'] )
end program
如果我对 call testA%add( ['toto','abcc','d,ef'] )
行进行注释,它就可以正常工作。但是如果我取消注释,我在编译过程中会出错
Error: Actual argument at (1) for INTENT(INOUT) dummy 'objA' of ELEMENTAL subroutine 'add' is a scalar, but another actual argument is an array`
我明白为什么用testA%write
调用是正确的,这是由于传递对象的intent(in)
;在这种情况下,编译器理解一个参数是标量形状,另一个是数组形状。
对于 testA%add( ['toto','abcc','d,ef'] )
,我还了解到它需要一个形状为 obj_A
的数组作为 intent(inout)
,因为为输入提供的文本是一个标量。因此,这不是正确的方法。
无论文本的形状如何,是否有将文本添加到 obj_A%Message
的正确方法?
使用 elemental
子例程时,您可以提供一个数组输入和一个 array 输出 [然后以元素方式进行操作]。但是,您正在尝试将数组输入分配给标量输出(此处:testA
)。
如果您使用大小为 3 的数组输出,您的例程将按预期工作:
module add_mod
implicit none
type obj_A
character(len=:), allocatable :: Message
contains
procedure, pass(objA) :: add
end type
contains
elemental subroutine add( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*),intent(in) :: text
objA%Message=objA%Message//text
end subroutine add
end module
program test
use add_mod
implicit none
type(obj_A) :: testA
type(obj_A) :: testB(3)
call testA%add('toto')
print *, testA%Message
call testB%add( ['toto','abcc','d,ef'] )
print *, testA%Message
print *, testB(1)%Message, testB(2)%Message, testB(3)%Message
end program
这是一个将字符串数组添加到标量输出的版本。请注意,由于这个星座,子程序不能是elemental
。但是,它可以是 pure
:
module add_mod
implicit none
type obj_A
character(len=:), allocatable :: Message
contains
procedure, pass(objA) :: add
end type
contains
pure subroutine add( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*), dimension(:), intent(in) :: text
integer :: i
do i=1,size(text)
objA%Message=objA%Message//text(i)
enddo !i
end subroutine add
end module
program test
use add_mod
implicit none
type(obj_A) :: testA
call testA%add(['toto'])
print *, testA%Message
call testA%add( ['toto','abcc','d,ef'] )
print *, testA%Message
end program
最后,要同时支持标量和数组参数,您需要提供并绑定多个实现,然后使用 generic
接口以相同的名称提供它们:
module add_mod
implicit none
type obj_A
character(len=:), allocatable :: Message
contains
generic :: add => add1, add2
procedure, pass(objA) :: add1
procedure, pass(objA) :: add2
end type
contains
pure subroutine add1( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*), dimension(:), intent(in) :: text
integer :: i
do i=1,size(text)
objA%Message=objA%Message//text(i)
enddo
end subroutine add1
pure subroutine add2( objA, text )
implicit none
class(obj_A), intent(inout) :: objA
character(len=*), intent(in) :: text
objA%Message=objA%Message//text
end subroutine add2
end module
program test
use add_mod
implicit none
type(obj_A) :: testA
call testA%add('toto')
print *, testA%Message
call testA%add( ['toto','abcc','d,ef'] )
print *, testA%Message
end program