operator overloading - Fortran: Accessing values from the return type of a function -
i have created derived type v, , included add function can use operator +.
however when
z = u + v
the operation not performed. think because z%kn
not being accessed.
however when
call vsum(z, u, v)
everything works expected
below declaration of derived type , overloading function vadd.
module vtest type :: v character (len=8) :: kn real, allocatable :: vc(:) contains procedure :: vadd generic :: operator (+) => vadd end type vtest contains function vadd (b, c) result (a) type (v) :: class (v), intent (in) :: b, c !!$ in vsum, use made of a% kn call vsum (a, b, c) end function vadd subroutine vsum (ta, tb, tc) type (v), intent (inout) :: ta type (v), intent (in) :: tb, tc logical :: la, lb, lc la = .false.; lb = .false.; lc = .false. select case (ta%kn) case ("real32") if (allocated (ta%vc)) la = .true. if (allocated (tb%vc)) lb = .true. if (allocated (tc%vc)) lc = .true. if (la .and. lb .and. lc) ta%vc = tb%vc + tc%vc end if end select end subroutine vsum end module vtest program test use vtest type (v) :: z z% kn = "real32" allocate (z% vc_real32(3)) write (*,*) "z = u + v" write (*,*) "z% kn: ", z% kn z = u + v write (*,*) "z% kn: ", z% kn write (*,*) "z: ", z% vc_real32 end program vtest
let's @ subroutine vsum
. work done in subroutine depends on definition of components of 3 objects ta
, tb
, tc
. summation proceed expect necessary allocatable components allocated , match of ta%kn
'real32'
.
there's no complete working example, things work when there call like
call vsum(z, u, w) ! v name of type, call variable w
z%kn
set 'real32'
.
however, defined operation
z = u + w
there function reference
z = vadd(u, w)
in there call
call vsum (a, b, c) ! actual arguments "z", u, w.
now, a
function result of vadd
. consequent of that, dummy argument intent(out)
a
undefined.
that means, essentially, when passed through vadd
z
makes vsum
undefined component kn
, unallocated component vc
. so, requirements summation not met (and indeed select case
forms invalid reference).
i suppose can comment on how fix issue, also.
in vsum
, you're taking, in effect, type of operation "result". instead, like
subroutine vsum (ta, tb, tc) type (v), intent (out) :: ta type (v), intent (in) :: tb, tc logical :: lb, lc lb = .false.; lc = .false. ! in here want consistency checking... select case (tb%kn) case ("real32") if (allocated (tb%vc)) lb = .true. if (allocated (tc%vc)) lc = .true. if (lb .and. lc) ta%vc = tb%vc + tc%vc ! ta%vc being automatically allocated end if end select end subroutine vsum
this, naturally, doesn't address seeming desire (from title) take type of operation result. could original subroutine approach, except in 1 instance isn't philosophy of fortran functions.
if want use defined operations, can't have operation defined left-hand side of assignment. in expression u+w
there isn't left-hand side, defined operation still expected behave. say, in statement
z = u + w
you aren't saying "z
result of operation +
applied u
, w
". but: "the operation +
applied u
, w
evaluated , result (through defined or implicit assignment) assigned z
". there assignment before "type of result" reached. why earlier on put z
actual argument in quotes.
Comments
Post a Comment