Topic: member and non-member operators


Author: Gregory Bond <gnb@itga.com.au>
Date: 1999/07/23
Raw View
I wrote:

> This makes (for
> example) integer-like class templates impossible:

Let me clarify this by adding

 ... without defining a zillion extra functions like
 template <class T> Int<T> operator+(Int<T>, int)
 template <class T> Int<T> operator+(Int<T>, unsigned)
 template <class T> Int<T> operator+(Int<T>, long)
 // etc

 template <class T> Int<T> operator+(int, Int<T>)
 template <class T> Int<T> operator+(unsigned, Int<T>)
 template <class T> Int<T> operator+(long, Int<T>)

 // Same for operator-, operator/, operator*, operator==, operator<<,
 // etc etc etc etc
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/07/20
Raw View
Since the article is multiposted to csc++ and clc++m, I am
cross-posting this reply.

On 19 Jul 1999 16:01:57 GMT, Alex Vinokur
<alexander.vinokur@telrad.co.il> wrote:

:
: Hi,
:
: Is there any difference between
:         member operators and
:         non-member ones?
:
: //========================================
: Example#1:
: class AAA
: {
:         public :
:                 AAA& operator+ (AAA& ins_i)

The return type is a bit strange.  Operator+ usually does not
modify its arguments.  I wonder to what the reference will refer?
Let's assume that the & is a typo and it returns an AAA by value.
It should then be a const member function and take a const parameter.

:                 {
:                         // stuff
:                 }
: };
:
: //========================================
: Example#2:
: class AAA
: {
: friend AAA operator+ (AAA& ins1_i, AAA& ins2_i);

How about some const's here also?

: };
:
: AAA operator+ (AAA& ins1_i, AAA& ins2_i)
: {
:         // stuff
: }
:
:
: //=========================================
:
:
: Are these implementations always equivalent?

No.  The difference is in conversions.  Assume a constructor AAA(int).

AAA a1(6), a2(9), a3;

a3 = a1 + a2; // either
a3 = a1 + 5;  // either, uses a1 + AAA(5)
a3 = 5 + a2;  // only for non-member with AAA(5) + a2

Conversions may not be applied to the lhs of a member function for
obvious reasons.

See the Effective C++ books by Scott Meyers for reasons to make
operator+ a non-member implemented in terms of an operator+= member.

AAA& AAA::operator+= (AAA const& rhs) {
   // stuff
   return *this;
   }

template <typename T>
T operator+ (T const& lhs, T const& rhs) { // friend not needed
   T tmp(lhs);
   tmp += rhs;
   return tmp;
   }

Operator+ always looks like this, but the template may be an overkill.

John
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gregory Bond <gnb@itga.com.au>
Date: 1999/07/22
Raw View
clamage@eng.sun.com (Steve Clamage) writes:

> Yes. Implicit type conversions are not applied to the argument
> corresponding to an implicit "this" parameter. The classic example
> is operator+ used for concatenating strings:

Trap for young players: This is only useful for non-template classes.
The rules for the interaction between argument deduction for template
classes with user-defined conversions mean that using friend operator
functions of templated classes don't work as expected. This makes (for
example) integer-like class templates impossible:

template <class T> class Int {
        T rep;
    public:
        Int(int);
        Int();
        friend Int operator+<>(Int, Int);
};

template <class T>
Int<T> operator+(Int<T> a, Int<T> b) {
        return a.rep + b.rep;
}

void foo()
{
        typedef Int<int> ii;

        ii a = 2; // OK
        ii b = 4; // OK

        ii c;

        c = a + b; // OK
        c = a + 2; // Not OK.
}

Greg,
who spent several days trying to work out why a fixed-point
class he was writing wasn't compiling right....
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Alex Vinokur <alexander.vinokur@telrad.co.il>
Date: 1999/07/19
Raw View
Hi,

Is there any difference between
        member operators and
        non-member ones?

//========================================
Example#1:
class AAA
{
        public :
                AAA& operator+ (AAA& ins_i)
                {
                        // stuff
                }
};

//========================================
Example#2:
class AAA
{
friend AAA operator+ (AAA& ins1_i, AAA& ins2_i);
};

AAA operator+ (AAA& ins1_i, AAA& ins2_i)
{
        // stuff
}


//=========================================


Are these implementations always equivalent?

        Thanks in advance,
        Alex




Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/07/19
Raw View
Alex Vinokur <alexander.vinokur@telrad.co.il> writes:

>Is there any difference between
>        member operators and
>        non-member ones?

Yes. Implicit type conversions are not applied to the argument
corresponding to an implicit "this" parameter. The classic example
is operator+ used for concatenating strings:

Implementation 1:
class string {
public:
 string(const char*);
 string operator+(const string&);
 ...
};

string s1("Hello");
string s2("World");
string s3 = s1         + " Heaven"; // ok
string s4 = "Goodbye " + s2;        // error

For s3, the literal is converted to a string, but for s4, the
conversion is not applied for the implicit "this" parameter.

Change the implementation to this one:
class string {
public:
 string(const char*);
 ... // no member operator+
};
string operator+(const string&, const string&);

Now all the code above is valid.

The reason for not converting arguments for "this" is so that you
don't apply implicit operations to a temporary object. When you write
 "Goodbye " + s2
you are really writing
 string("Goodbye ").operator+(s2);

In other words, you create a tempory string object, then apply
a member function to it. In this case it probably doesn't matter.
But normally when you apply a member function to an object, you
don't expect the object to be a temp that disappears immediately
afterward.

--
Steve Clamage, stephen.clamage@sun.com


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/07/19
Raw View
On 19 Jul 1999 16:01:57 GMT, Alex Vinokur

>Is there any difference between
>        member operators and
>        non-member ones?

Member functions: compiler does not do conversions on the LHS.  Just the RHS.
Non-member: compiler does conversions on both ths LHS or RHS.

Non-const member function: LHS can be a temporary.
Non-members with first arg a non-const reference: LHS can't be a temporary.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]