![]() |
Blitz Support : |
From: Julian C. Cummings (cummings_at_[hidden])
Date: 2005-03-23 06:00:41
Hello Paul,
The basic reason for this behavior has to do with how inheritance works. In
the header file <blitz/vecbops.cc>, there is a binary subtraction operator
defined for a pair of TinyVector objects that returns a _bz_VecExpr object
(an internal blitz type that represents an expression involving vector-like
objects). When you subtract two of your Point class objects, the compiler
sees that it can use the binary subtraction operator for two TinyVectors,
since a Point is a TinyVector. Now, there is an assignment operator defined
for TinyVector that assigns from a _bz_VecExpr (vector-like expression). So
in the case of subtracting two TinyVectors and assigning the result to a
TinyVector, this assignment operator is used. But assignment operators are
not inherited and implicitly available in a derived class. (The main reason
for this is to avoid "partially assigning" only the Base class part of a
Derived type object.) So in the case of subtracting two Points, the
compiler does not automatically invoke the assignment operator from the
TinyVector class. Casting the expression to a Point before assigning it
works if you have a Point constructor defined that takes a TinyVector
argument because the compiler can use the TinyVector constructor that takes
a _bz_VecExpr object as its argument, and then convert this into a Point
object.
As it turns out, TinyVector assignment from a _bz_VecExpr and construction
from a _bz_VecExpr are both implemented using the same optimized function
(see <blitz/tinyvec.cc> for details). The only difference would be the
intermediate construction of a temporary Point object during the assignment.
Good optimizing compilers probably eliminate this extra temporary once the
loop over vector elements is unrolled. In any case, you will retain the
most important optimization, which is that the expression result will be
completely evaluated and assigned to the result vector element by element,
with no partial results computed or stored. I think you are stuck with the
ugliness of casting the result to type Point though. The alternatives would
be to define an operator= in Point that took a _bz_VecExpr object and
invoked the TinyVector base class operator=, or to put the TinyVector
operator= from a _bz_VecExpr in the scope of derived class Point with a
using declaration. Either way, the internal blitz type _bz_VecExpr intrudes
on the definition of your Point class.
Perhaps there is a better way to do this by providing a set of macros that
could make your Point class "expression capable", along the lines of what
the Portable Expression Template Engine (PETE) did for generic container
classes. Have you checked out tvmet, the tiny vector and matrix expression
template package that was derived from the original blitz TinyVector and
TinyMatrix classes? I haven't checked into this, but perhaps tvmet provides
this capable to reuse the expression template machinery for a user-defined
"tiny" type that acts as a concrete data type with fixed size at compile
time.
Regards, Julian C.
Dr. Julian C. Cummings
Staff Scientist, CACR/Caltech
(626) 395-2543
cummings_at_[hidden]
> -----Original Message-----
> From: blitz-support-bounces_at_[hidden]
> [mailto:blitz-support-bounces_at_[hidden]] On Behalf Of
> Dawson, Paul (UK Filton)
> Sent: Wednesday, March 09, 2005 5:47 AM
> To: blitz-support_at_[hidden]
> Subject: [Blitz-support] vector expressions
>
>
>
> Sorry if this question has come up before, but I've had a
> long search of the archive, and I can't seem to answer it.
>
> I have a templated class Point<S> which inherits from TinyVector<S,3>.
>
> When I do something like:
>
> Point<S> myFunction() {
> Point<S> p1;
> Point<S> p2;
> ..
> ..
> return p1 - p2;
> }
>
> I get an error to the effect that the result of p1 - p2 is
> not of type Point, but a blitz vector expression.
>
> I can avoid this error by casting the return to a Point i.e.
> "return static_cast<Point>(p1 -p2);", but it seems to me that
> I might be losing the efficiency that comes from using vector
> expressions, and also making the code harder to understand.
>
> If I do the same thing using tinyvectors explicitly, I don't
> have the same problem. I don't understand why my derived
> Point class does not have the same behaviour.
>
> Many thanks, Paul.
>
> ---------------------------
> Paul Dawson
> paul.dawson3_at_[hidden]
> 0117 302 8311
>
> ---------------------------
> Paul Dawson
> paul.dawson3_at_[hidden]
> 0117 302 8311
>
> ********************************************************************
> This email and any attachments are confidential to the
> intended recipient and may also be privileged. If you are not
> the intended recipient please delete it from your system and
> notify the sender. You should not copy it or use it for any
> purpose nor disclose or distribute its contents to any other person.
> ********************************************************************
>
> _______________________________________________
> Blitz-support mailing list
> Blitz-support_at_[hidden]
> http://www.oonumerics.org/mailman/listinfo.cgi/blitz-support
>