Fortran 重载二进制运算符时是否可以避免临时存储?
我对向量类使用了运算符重载Fortran 重载二进制运算符时是否可以避免临时存储?,fortran,operator-overloading,fortran2008,Fortran,Operator Overloading,Fortran2008,我对向量类使用了运算符重载 interface operator(+) module procedure :: vec_add_sv !< scalar + vector module procedure :: vec_add_vs !< vector + scalar module procedure :: vec_add_vv !< vector + vector end interface operator(+) :
interface operator(+)
module procedure :: vec_add_sv !< scalar + vector
module procedure :: vec_add_vs !< vector + scalar
module procedure :: vec_add_vv !< vector + vector
end interface operator(+)
:
:
function vec_add_sv( s, v1 ) result( v2 )
type(Vector) :: v2
real(dp), intent(in) :: s
type(Vector), intent(in) :: v1
integer :: i, n
n = v1%size()
call v2%resize(n)
do i=1,n
V2%q(i) = s + V1%q(i)
end do
end function vec_add_sv
:
:
v2 = s + v1
在函数vec\u add\u sv和子例程vector\u assign中放入write语句,我注意到
vec2 = scalar + vector
它调用了vec\u add\u sv函数和vector\u assign子例程。这表明vec\u add\u sv函数为其返回创建了一个临时向量,然后将该临时向量传递给vector\u assign子例程。结果是我在向量元素中循环了两次
有没有一种方法可以在不创建临时存储的情况下实现二进制运算符
我认识到,如果你做了像a=B+(C*D)这样的事情,那么(C*D)就需要一个临时的,用于B+temp的临时的。
但是如果我只是做一个简单的运算a=B+C
我想要一些相当于
interface add
subroutine vec_add( A, B, C )
type(vector), intent(out) :: A
type(vector), intent(in) :: B
type(vector), intent(in) :: C
end subroutine vec_add
end interface add
接口运算符(+)要求模块过程是函数而不是子例程对所有Fortran问题使用标记。可以添加要指定的版本标记。几乎没有人看到你的问题,因为它有一个标签,人们不会跟随。16个追随者,3200个追随者。标记在StackOverflow中非常重要。“这表示vec_add_sv函数为其返回创建了一个临时向量,然后将该临时向量传递给vector_assign子例程。”您认为这是为什么?编译器可以做很多聪明的事情来避免临时性的问题。可能创建了一个临时的,但应该首先确认。为什么您需要自己的
vector\u assign
例程?为什么内在数组分配不足?Vladimir-I向操作符、分配和最终过程添加了全局计数器,并计算了超出范围的对象数。在最终确定的块4对象的末尾执行A=B+C,执行1个运算符,调用1个赋值。
interface add
subroutine vec_add( A, B, C )
type(vector), intent(out) :: A
type(vector), intent(in) :: B
type(vector), intent(in) :: C
end subroutine vec_add
end interface add