Newsgroups: comp.lang.c++
Path: utzoo!censor!geac!alias!barney!rae
From: Reid Ellis <rae@gpu.utcs.toronto.edu>
Subject: Re: friend operator +(l,r) vs. operator +(r)
Message-ID: <rae.660684441@barney>
Sender: Reid Ellis <rae%alias@csri.toronto.edu>
Reply-To: Reid Ellis <rae@gpu.utcs.toronto.edu>
Organization: Alias Research, Inc. Toronto ON Canada
References: <1990Nov21.053431.22340@actrix.co.nz>
	<1990Nov22.230835.26713@clear.com> <rae.659682898@earth>
	<1990Nov30.131808.19717@clear.com>
Date:  8 Dec 90 19:27:21 GMT

I had said:
>	Does anyone else think that
>
>		operator+(const type1 &, const type2 &);
>
>	should have a return type of type1 at all times?


To which Bob Martin <rmartin@clear.com> replied:
>Although I agree that there is a set of functions f(a,b) which should
>always return elements of type a, I don't think the rule is global.
>Furthermore IMHO it should not be applied to an operator which is
>expected to be commutative (like operator+).  Otherwise you are
>setting up scenarios where a+b != b+a.  IMHO this would lead to
>support nightmares.

I'd have to agree with you.  We've been working with points and vectors
and have found that the following are useful operations:

vector = point  - point	 |  vector point::operator-(const point &) const
point  = point  + vector |  point  point::operator+(cont vector &) const
point  = vector + point	 |  point  vector::operator+(const point &p) const

So much for my statement. :-)

Note that point+point is ilegal.  Also note that [conceptually]
vector-point could be considered illegal whereas point-vector might
not since unary- on a vector has a coordinate-frame-independant
meaning, whereas unary- on a point is specific to the frame of
reference, if valid at all.

But still, it remains whether it is "better" to have friend functions
or methods to handle these cases.  I am reluctant to use friends,
mostly because I can't be selective about how much they know.  It's an
all-or-nothing thing.

One way to avaoid friends is to define the operator in both classes
but define one as calling the other.  For instance, in the last case
above, we could define "vector+point" as this:

point vector::operator+(const point &p) const { return point + *this; }

and have all the "real" code in "point::operator+(const vector &)".
Note that this makes it very important that any "operator+" type
methods that return values on the stack be declared "const".

Actually, for this case you would need two friend functions anyways,
but you get the idea.

					Reid
--
Reid Ellis  176 Brookbanks Drive, Toronto ON, M3A 2T5 Canada
rae@gpu.utcs.toronto.edu      ||  rae%alias@csri.toronto.edu
CDA0610@applelink.apple.com   ||             +1 416 446 1644
