By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,916 Members | 1,319 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,916 IT Pros & Developers. It's quick & easy.

syntax for overloading operators

P: n/a
Hello,

After seeing some examples about operator overloading, I'm still a bit
confused about the general syntax. The following is what I think, not
sure whether it's correct.

1. For a unary operator that's a member of a class, its form is
usually

"operatorP()" (where P is the operator's name).

If it's a non-member operator, then its form is

"operatorP(arg)"

2.For a binary operator that's a member of a class, its form is:

operatorP(arg),

where arg is the right argument of P.

If it's a non-member operator, then its form is

"operatorP(argLeft,argRight)"

Is there anything I've missed? Moreover, can I overload a ternary
operator? I think there's only one ternary operator, which is "a ?
b:c".

Many thanks,
Jess

May 21 '07 #1
Share this Question
Share on Google+
19 Replies


P: n/a
* Jess:
>
After seeing some examples about operator overloading, I'm still a bit
confused about the general syntax. The following is what I think, not
sure whether it's correct.

1. For a unary operator that's a member of a class, its form is
usually

"operatorP()" (where P is the operator's name).

If it's a non-member operator, then its form is

"operatorP(arg)"

2.For a binary operator that's a member of a class, its form is:

operatorP(arg),

where arg is the right argument of P.

If it's a non-member operator, then its form is

"operatorP(argLeft,argRight)"

Is there anything I've missed?
For operator++ and operator-- you differentiate between prefix and
postfix forms via a dummy int second argument.

Moreover, can I overload a ternary operator?
No.

I think there's only one ternary operator, which is "a ? b:c".
Yes.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
May 21 '07 #2

P: n/a
Jess wrote:
After seeing some examples about operator overloading, I'm still a bit
confused about the general syntax. The following is what I think, not
sure whether it's correct.

1. For a unary operator that's a member of a class, its form is
usually

"operatorP()" (where P is the operator's name).
In literature you'll find '@' is used instead of 'P'.
If it's a non-member operator, then its form is

"operatorP(arg)"

2.For a binary operator that's a member of a class, its form is:

operatorP(arg),

where arg is the right argument of P.

If it's a non-member operator, then its form is

"operatorP(argLeft,argRight)"

Is there anything I've missed?
Not really. Overloaded operators can take const arguments as well,
so when it's a member, it can have the form 'rv operator@() const'.
Moreover, can I overload a ternary
operator?
No. Neither can you overload '.' (dot), nor 'sizeof'. Also you
probably shouldn't overload logical OR and logical AND (you may,
however).
I think there's only one ternary operator, which is "a ?
b:c".
Right.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 21 '07 #3

P: n/a
Victor Bazarov wrote:
Also you
probably shouldn't overload logical OR and logical AND (you may,
however).
Is this a recommendation because the most common case where you
might want to overload || and && is to support expressions like:

MyClass a, b;
...
if(a || b) ...

and this is better done by instead defining an "operator bool()"
in 'MyClass'?
May 21 '07 #4

P: n/a
Juha Nieminen wrote:
Victor Bazarov wrote:
>Also you
probably shouldn't overload logical OR and logical AND (you may,
however).

Is this a recommendation because the most common case where you
might want to overload || and && is to support expressions like:

MyClass a, b;
...
if(a || b) ...

and this is better done by instead defining an "operator bool()"
in 'MyClass'?
I don't know what the most common case in which you might want to
overload || and &&. Honestly, I don't. I only know that if those
are overloaded, the logic essentially changes -- no more "short
circuit" evaluation.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 21 '07 #5

P: n/a

"Juha Nieminen" <no****@thanks.invalidwrote in message
news:46**********************@news.song.fi...
Victor Bazarov wrote:
>Also you
probably shouldn't overload logical OR and logical AND (you may,
however).

Is this a recommendation because the most common case where you
might want to overload || and && is to support expressions like:

MyClass a, b;
...
if(a || b) ...

and this is better done by instead defining an "operator bool()"
in 'MyClass'?
IMHO the reason is the confusion that overloaded &&/|| operators cannot
shortcut: to pass arguments to the overloaded operation the compiler need to
evaluate both parameters, and this can be confusing if you expect that b is
not evaluated if a has some specific property...

--
Marco
May 21 '07 #6

P: n/a

"*PaN!*" <sp***@pinningids.orgwrote in message
news:FR*****************@tornado.fastwebnet.it...
IMHO the reason is the confusion that overloaded &&/|| operators cannot
shortcut: to pass arguments to the overloaded operation the compiler need
to evaluate both parameters, and this can be confusing if you expect that
b is not evaluated if a has some specific property...
I should have reread the sentence... ok, as Victor said, is that you no
longer have shortcut evaluation ;)

--
Marco
May 21 '07 #7

P: n/a
On 2007-05-21 06:47:40 -0700, Juha Nieminen <no****@thanks.invalidsaid:
Victor Bazarov wrote:
>Also you
probably shouldn't overload logical OR and logical AND (you may,
however).

Is this a recommendation because the most common case where you
might want to overload || and && is to support expressions like:

MyClass a, b;
...
if(a || b) ...

and this is better done by instead defining an "operator bool()"
in 'MyClass'?
I would actually recommend against writing an "operator bool()" in
almost any circumstance. With the implicit conversion from bool to any
arithmetic type, some counterintuitive (at first glance) conversions
will be allowed by the compiler.
--
Clark S. Cox III
cl*******@gmail.com

May 21 '07 #8

P: n/a
Clark Cox wrote:
On 2007-05-21 06:47:40 -0700, Juha Nieminen <no****@thanks.invalid>
said:
>Victor Bazarov wrote:
>>Also you
probably shouldn't overload logical OR and logical AND (you may,
however).

Is this a recommendation because the most common case where you
might want to overload || and && is to support expressions like:

MyClass a, b;
...
if(a || b) ...

and this is better done by instead defining an "operator bool()"
in 'MyClass'?

I would actually recommend against writing an "operator bool()" in
almost any circumstance. With the implicit conversion from bool to any
arithmetic type, some counterintuitive (at first glance) conversions
will be allowed by the compiler.
To Juha:

.... and as a fairly common replacement for 'operator bool()' you might
consider 'operator void*()' which would return a null pointer in case
of 'false' and "true" otherwise (don't return 'this', others might
figure it out and try taking advantage of it).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 21 '07 #9

P: n/a
Clark Cox wrote:
I would actually recommend against writing an "operator bool()" in
almost any circumstance. With the implicit conversion from bool to any
arithmetic type, some counterintuitive (at first glance) conversions
will be allowed by the compiler.
I thought the C++ standard forbids two implicit conversions to be
performed on the same type.

In other words, if you have a class A with an operator bool() defined,
this is valid:

A a;
bool b = a;

but this is not (and should give a compiler error):

A a;
int b = a;

because it would require *two* implicit conversions.

Thus I don't really see the problem you are referring to.
May 21 '07 #10

P: n/a
Juha Nieminen wrote:
Clark Cox wrote:
>I would actually recommend against writing an "operator bool()" in
almost any circumstance. With the implicit conversion from bool to any
arithmetic type, some counterintuitive (at first glance) conversions
will be allowed by the compiler.

I thought the C++ standard forbids two implicit conversions to be
performed on the same type.
The limit is two user-defined conversions. There can be additional
standard conversions along the way.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
May 21 '07 #11

P: n/a
Juha Nieminen wrote:
Clark Cox wrote:
>I would actually recommend against writing an "operator bool()" in
almost any circumstance. With the implicit conversion from bool to
any arithmetic type, some counterintuitive (at first glance)
conversions will be allowed by the compiler.

I thought the C++ standard forbids two implicit conversions to be
performed on the same type.

In other words, if you have a class A with an operator bool()
defined, this is valid:

A a;
bool b = a;

but this is not (and should give a compiler error):

A a;
int b = a;

because it would require *two* implicit conversions.

Thus I don't really see the problem you are referring to.
Actually, a standard conversion *sequence* followed by a user-defined
conversion, followed by another standard conversion *sequence*, is
what's allowed (AFAICT). See 13.3.3.1.2/1.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 21 '07 #12

P: n/a
Jess schrieb:
Hello,

After seeing some examples about operator overloading, I'm still a bit
confused about the general syntax. The following is what I think, not
sure whether it's correct.

1. For a unary operator that's a member of a class, its form is
usually

"operatorP()" (where P is the operator's name).

If it's a non-member operator, then its form is

"operatorP(arg)"
Think of it this way:

For unary operators you have: operator@(arg),
for binary operators: operator@(left, right),

and if implemented as member function, the first (left) argument is
discarded because it is the implicit 'this' parameter instead.
Is there anything I've missed? Moreover, can I overload a ternary
operator? I think there's only one ternary operator, which is "a ?
b:c".
You missed the function call operator. It is always a member function and
looks like:

return_type operator() () // or:
return_type operator() (arg1) // or:
return_type operator() (arg1, arg2) // and so on...

Where you can have as many args as you want.

In addition, read here:
http://www.parashift.com/c++-faq-lit...erloading.html
(especially 13.5)

--
Thomas
http://www.netmeister.org/news/learn2quote.html
May 22 '07 #13

P: n/a
On May 22, 12:51 am, Jess <w...@hotmail.comwrote:
1. For a unary operator that's a member of a class, its form is
usually

"operatorP()" (where P is the operator's name).

If it's a non-member operator, then its form is

"operatorP(arg)"
There's a special case for the postfix operator++,
and operator-- of course, even though it is unary
it takes an extra 'dummy argument' so that it has
a different signature from the prefix operator.

May 22 '07 #14

P: n/a
On May 21, 7:17 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Clark Cox wrote:
On 2007-05-21 06:47:40 -0700, Juha Nieminen <nos...@thanks.invalid>
said:
Victor Bazarov wrote:
Also you
probably shouldn't overload logical OR and logical AND (you may,
however).
Is this a recommendation because the most common case where you
might want to overload || and && is to support expressions like:
MyClass a, b;
...
if(a || b) ...
and this is better done by instead defining an "operator bool()"
in 'MyClass'?
I would actually recommend against writing an "operator bool()" in
almost any circumstance. With the implicit conversion from bool to any
arithmetic type, some counterintuitive (at first glance) conversions
will be allowed by the compiler.
... and as a fairly common replacement for 'operator bool()' you might
consider 'operator void*()' which would return a null pointer in case
of 'false' and "true" otherwise (don't return 'this', others might
figure it out and try taking advantage of it).
In the case of [io]stream, conversion to bool was considered
completely inacceptable because bool converts implicitly to
something for which << and >are legal operators. Which in
turn can lead to some very surprising ambiguities and/or
overload resolutions. It's not, IMHO, generally a problem, if
the object in question doesn't support any arithmetic operators,
and would never be used in a context where the ambiguity might
occur.

I seem to recall too that there are contexts where void* is also
ambiguous (although I forget what), and that the "ideal"
solution was to return a pointer to a private class. But
whatever the problem was, it's never shown up in practice, at
least in my code, so I generally don't bother.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 22 '07 #15

P: n/a
On May 22, 2:37 am, "Thomas J. Gritzan" <Phygon_ANTIS...@gmx.de>
wrote:
Jess schrieb:
[...]
You missed the function call operator. It is always a member function and
looks like:
return_type operator() () // or:
return_type operator() (arg1) // or:
return_type operator() (arg1, arg2) // and so on...
And user defined conversions, which while not really an operator
overload, has the syntax of one.

When considering operator overloading, one should not forget
that they are one of the most powerful tools ever invented for
obfuscation. When considering there use, the rule is: when in
doubt, don't. If your class is an abstraction of an arithmetic
type, of course, *not* overloading the usual arithmetic
operators is obfuscation, as anyone who's had to use user
defined arithmetic types in Java can attest; if it is an
abstraction of a pointer, of course, unary * and -are a must,
and if it is an indexable container, []. Beyond that, << is
formatted output, and >is formatted input, and anything else
is abuse.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 22 '07 #16

P: n/a
James Kanze wrote:
>
I seem to recall too that there are contexts where void* is also
ambiguous (although I forget what), and that the "ideal"
solution was to return a pointer to a private class. But
whatever the problem was, it's never shown up in practice, at
least in my code, so I generally don't bother.
I think the problem isn't ambiguity, but the perceived risk that someone
will write "delete obj;". If obj can be implicitly converted to void*,
the resulting pointer gets passed to operator delete.

The usual recommendation to cure this is to return a pointer to a member
of the class. That's not a valid argument to delete, so the compiler
will diagnose this error. There are several places in the current
working draft for C++0x that piously recite that the "unspecified
boolean type" should be a pointer to member.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
May 22 '07 #17

P: n/a
On May 22, 1:56 pm, Pete Becker <p...@versatilecoding.comwrote:
James Kanze wrote:
I seem to recall too that there are contexts where void* is also
ambiguous (although I forget what), and that the "ideal"
solution was to return a pointer to a private class. But
whatever the problem was, it's never shown up in practice, at
least in my code, so I generally don't bother.
I think the problem isn't ambiguity, but the perceived risk that someone
will write "delete obj;". If obj can be implicitly converted to void*,
the resulting pointer gets passed to operator delete.
The usual recommendation to cure this is to return a pointer to a member
of the class. That's not a valid argument to delete, so the compiler
will diagnose this error. There are several places in the current
working draft for C++0x that piously recite that the "unspecified
boolean type" should be a pointer to member.
Hmmm. I seem to remember someone recommending using a pointer
to a private member class, for reasons of overload resolution,
but I don't remember the details. In the end, I can't remember
ever having had an ambiguity with void*, and I've never, ever
seen a case where someone accidentally wrote something like
"delete std::cout ;". (And I've been reviewing C++ code for
well over 15 years, and I've seen some pretty bad code.) So it
seems a case of adding complexity and obfuscation in order to
avoid and/or detect errors that never occur in practice.

In my own code (today at least), when I want a boolean type, I
spell it "bool". Including in conversion operators. About the
only time I'd make an exception is when the class also supports
arithmetic operators (where the conversion to int could come
into play), and conversions might be involved in those
arithmetic operations (because without conversions, there will
always be an exact match). In practice, in my code, that means
stream classes, and nothing else. (And since my binary stream
classes all derived from std::basic_ios, I don't have to write
it myself there, either.)

(Note that I do use the "pointer to private class" as an
argument to operator== for smart pointers. But the goal there
isn't to have a boolean type; the goal is to allow comparison
with a null pointer constant, but not with anything else. And I
don't like it, but I've not found a better solution.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 23 '07 #18

P: n/a
* Pete Becker:
James Kanze wrote:
>>
I seem to recall too that there are contexts where void* is also
ambiguous (although I forget what), and that the "ideal"
solution was to return a pointer to a private class. But
whatever the problem was, it's never shown up in practice, at
least in my code, so I generally don't bother.

I think the problem isn't ambiguity, but the perceived risk that someone
will write "delete obj;". If obj can be implicitly converted to void*,
the resulting pointer gets passed to operator delete.

The usual recommendation to cure this is to return a pointer to a member
of the class. That's not a valid argument to delete, so the compiler
will diagnose this error. There are several places in the current
working draft for C++0x that piously recite that the "unspecified
boolean type" should be a pointer to member.
The problem is the implicit conversion to something that can be used as
bool. The solution is to not provide implicit conversion. Naming
things is good, and it's even recommended by the Bible (go forth and
name all in heaven and on earth and wherever your fancy takes you).

Cheers,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
May 23 '07 #19

P: n/a
James Kanze wrote:
In the end, I can't remember
ever having had an ambiguity with void*, and I've never, ever
seen a case where someone accidentally wrote something like
"delete std::cout ;". (And I've been reviewing C++ code for
well over 15 years, and I've seen some pretty bad code.) So it
seems a case of adding complexity and obfuscation in order to
avoid and/or detect errors that never occur in practice.
There's definitely a tendency with inexperienced designers to try to
solve every problem they can think of.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
May 23 '07 #20

This discussion thread is closed

Replies have been disabled for this discussion.