Overloading <<, number of arguments

P

Peter v. N.

Hi all,

Maybe this has been asked a million times before.
In that case I'm sorry for being to lazy to search
the Internet or look it up in a decent C++ reference:

I read in O'Reilly's C++ Pocket reference (see also
http://www.oreilly.com/catalog/cpluspluspr/errata/ ,
btw not that bad),
that the operator << has to be overloaded like this:

#include <ostream>
std::eek:stream &MyClass::eek:perator<<(std::eek:stream &pOS, MyClass &pObj) const
{
return pOS << pObj.someMethod();
}

Implemented that way, Eclipse 3.2 (CDT) with gcc 4.0.1
(i686-apple-darwin8-gcc-4.0.1) report that << must take one and only
one argument. That's strange, isn't it?

What's the default implementation now?

Thank you for a hint pointing me in the right direction.

Brgds,
Peter
 
M

Mike Wahler

Peter v. N. said:
Hi all,

Maybe this has been asked a million times before.
In that case I'm sorry for being to lazy to search
the Internet or look it up in a decent C++ reference:

I read in O'Reilly's C++ Pocket reference (see also
http://www.oreilly.com/catalog/cpluspluspr/errata/ ,
btw not that bad),
that the operator << has to be overloaded like this:

#include <ostream>
std::eek:stream &MyClass::eek:perator<<(std::eek:stream &pOS, MyClass &pObj) const
{
return pOS << pObj.someMethod();
}

Then it's wrong.
Implemented that way, Eclipse 3.2 (CDT) with gcc 4.0.1
(i686-apple-darwin8-gcc-4.0.1) report that << must take one and only
one argument. That's strange, isn't it?
No.


What's the default implementation now?

Thank you for a hint pointing me in the right direction.

There are two possible ways to write this overload;
as a member function, in which case the signature is:

std::eek:stream& T::eek:perator<<(std::eek:stream&);

(an object of the user defined type ('T') is implied
as the left-hand operand.)

or as a non-member function:

std::eek:stream& operator<<(std::eek:stream&, const T&);

I suggest using a real C++ text(s) as your primary information
source, rather than a 'pocket guide'.

-Mike
 
S

Salt_Peter

Peter said:
Hi all,

Maybe this has been asked a million times before.
In that case I'm sorry for being to lazy to search
the Internet or look it up in a decent C++ reference:

I read in O'Reilly's C++ Pocket reference (see also
http://www.oreilly.com/catalog/cpluspluspr/errata/ ,
btw not that bad),
that the operator << has to be overloaded like this:

#include <ostream>
std::eek:stream &MyClass::eek:perator<<(std::eek:stream &pOS, MyClass &pObj) const
{
return pOS << pObj.someMethod();
}

No sir, thats impossible. All non-static and non-const member functions
have a hidden this parameter that already passes the object itself. So
the above, as clearly mentioned by the compiler, needs only a reference
to a std::eek:stream and it can't be const.
Only a dead brain would think that passing an instance of MyClass to
another instance of MyClass to stream its contents makes sense. It
doesn't and it never will.

std::eek:stream& MyClass::eek:perator<<(std::eek:stream& os)
{
...
}

And, since such an operator is more usefull as a global operator
overload, its often found as a friend of the class with a const
reference to an instance of the class:

MyClass
{
...
friend std::eek:stream&
operator<<(std::eek:stream& r_os, const MyClass& r_obj)
{
... // implemeneted here or globally
}
};

Now please note the placement of the reference operator. Its critical
because it clearly states the intentions of the operator. These are
references, not addresses.
Implemented that way, Eclipse 3.2 (CDT) with gcc 4.0.1
(i686-apple-darwin8-gcc-4.0.1) report that << must take one and only
one argument. That's strange, isn't it?

What's the default implementation now?

Typically, the default is the global op<< declared as a friend. Why?
Because these are often templated and they need to be globally
accessisible when streaming to std::cout.
 
P

Peter v. N.

Thank you for your explanations.
As you may have noticed, I'm a bloody beginner in C++
influenced by academia Java ;-)
 
S

Salt_Peter

Peter said:
Thank you for your explanations.
As you may have noticed, I'm a bloody beginner in C++
influenced by academia Java ;-)

Your questions are welcome, you might consider taking a peek at the
FAQ.
http://www.parashift.com/c++-faq-lite/index.html

Although i haven't found any section that deals with the specifics of
the stream operator overrides.
Please note, our goal is not to discourage you from asking questions.
Rather, there is a logic behind why things are the way they are. So its
not an issue of "its done like that because we said so". The goal is to
illustrate the reasonings behind the issues.
You'll find C++ to be a language where there is never only one way of
doing it. So you need to use your brain cells (or, as in my case, what
left of them) to come up with a solution that doesn't invoke undefined
behaviour.
 
M

Marcus Kwok

Mike Wahler said:
There are two possible ways to write this overload;
as a member function, in which case the signature is:

std::eek:stream& T::eek:perator<<(std::eek:stream&);

(an object of the user defined type ('T') is implied
as the left-hand operand.)

[Directed towards the OP]
Yes, but this usage is non-idiomatic. If you do it like this, then you
would use it like:

myObj << std::cout;

which is backwards from the common idiom.
or as a non-member function:

std::eek:stream& operator<<(std::eek:stream&, const T&);

This usage is more natural, and allows for chaining the output together:

std::cout << myObj << myObj2;
 
P

Peter v. N.

Salt_Peter said:
Your questions are welcome, you might consider taking a peek at the
FAQ.
http://www.parashift.com/c++-faq-lite/index.html

This is (one of) the best site(s) about C++. I use it often
to look up things (theory etc.).
Although i haven't found any section that deals with the specifics of
the stream operator overrides.
Please note, our goal is not to discourage you from asking questions.
Rather, there is a logic behind why things are the way they are. So its
not an issue of "its done like that because we said so". The goal is to
illustrate the reasonings behind the issues.
You'll find C++ to be a language where there is never only one way of
doing it. So you need to use your brain cells (or, as in my case, what
left of them) to come up with a solution that doesn't invoke undefined
behaviour.

That's what I like about C++: design your own philosophy [as long as
it's technically correct, that is]. But what's also very important to
me, whenever I learn a new language (be it human or more computer
oriented), is to grasp the culture of the community.

BTW: I did not cite correctly O'Reilly's C++ pocket reference concerning
the overload of the << operator. So my apologies if I cast a damning
light on that...(if one can say so in English).

Watch out for my future posts *g*
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top