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 ]