Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!usc!samsung!emory!gatech!udel!rochester!kodak!ispd-newsserver!tuna!randolph From: randolph@tuna.ssd.kodak.com (Gary L. Randolph) Newsgroups: comp.lang.c++ Subject: Re: friend operator +(l,r) vs. operator +(r) Message-ID: <1990Nov21.140621.4229@ssd.kodak.com> Date: 21 Nov 90 14:06:21 GMT References: <11759@hubcap.clemson.edu> Sender: news@ssd.kodak.com Organization: Eastman Kodak Lines: 78 In article <11759@hubcap.clemson.edu> grimlok@hubcap.clemson.edu (Mike Percy) writes: >I've tried and tried to get a handle on this question from various >sources, but haven't been enlightened... >What semantic/operational and/or stylistic differences are there >between these two definitions? >class foo { >... >public: > foo& operator +(foo& rhs); >} >and >class foo { >... >public: > friend foo& operator +(foo& lhs, foo&rhs); >} > >I must be missing something, because to me these effectively are the >same thing, but the first can operate on this. ^^^^^^^^^^^^^^? "requires" The best way to see the difference is by trying to use each. Say the member function is defined (No friend yet). Assume for the sake of example that a constructor, foo::foo(int), exists. The following: main(){ foo a,b; a + b; //ok b + a; //of course a + 2; //Fine, equivalent to a + foo(2); 2 + a; //Problem Why? If operator+ is a member, then operator+ must be called on behalf of an object. (Pg 253 of ARM states that for dot/arrow notation, the first expression must be an object/pointer to object.) So, why can't the 2 be converted to an object of type foo and then have operator+ applied to that temporary? As you know, a + 2; becomes a.operator(2); Pg 333 (ARM) states that, for binary operators of the form x.operator+(y) NO USER-DEFINED CONVERSIONS WILL BE APPLIED TO x. So, for a + 2, the literal, 2, can be converted, but the a *must* be an object of type foo. So, 2 + a; fails. Note that no non-foo object can be used as the left operand. This restriction is NOT made for calls of the form operator+(2, a); so user-defined conversion can be made on the non-foo 2. So, if a non-foo is to be used as the left operand, a friend is preferred. Note that friendship is only necessary for accessing a foo's private parts. If accessor functions were available, then the NONmember function is still required, but friendship is not. Gary Randolph Eastman Kodak Company