473,408 Members | 2,734 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

syntax for overloading operators

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
19 2262
* 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
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
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
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

"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

"*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
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
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
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
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
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
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
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
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
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
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
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
* 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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

699
by: mike420 | last post by:
I think everyone who used Python will agree that its syntax is the best thing going for it. It is very readable and easy for everyone to learn. But, Python does not a have very good macro...
13
by: denis wendum | last post by:
In a nutshell: What is the equivalent of __radd__ (wich overloads the right hand side of +) when overloading the comparison operators <,>,== and so on. My first guess __rlt__ for overloading the...
7
by: Petr Prikryl | last post by:
Hi, Summary: In my opinion, the C-like prefix increment and decrement operators (++i and --i) should be marked as "syntax error". Current situation: try... (Python 2.4 (#60, ...)) >>> i =...
2
by: bq | last post by:
Hello, This post is really two questions. Question 1: What is the current status on a revision of ISO C++, specifically regarding plans for overloading composite operators? Some people in this...
20
by: KL | last post by:
I am working on a school assignment, so please don't tell me the solution. I just want some direction. I am supposed to overload the >, <, ==, !=, >=, and <= operators using bool. I am having...
4
by: jelle | last post by:
Hi, I use python quite a bit to couple different programs together. Doing so has been a _lot_ easier since subprocess came around, but would really like to be able to use the succinct shell...
5
by: Jerry Fleming | last post by:
As I am newbie to C++, I am confused by the overloading issues. Everyone says that the four operators can only be overloaded with class member functions instead of global (friend) functions: (), ,...
15
by: PengYu.UT | last post by:
Hi, It seems that C++ does not allow overloading operators for primative types, e.g. int, double. I'm wondering whether it is ture or there is some walk-around? Thanks, Peng #include...
8
by: Wayne Shu | last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition). When I read chapter 11 Operator Overloading, I have two questions. 1. In subsection 11.2.2 paragraph 1, B.S. wrote "In particular,...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.