473,466 Members | 1,397 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Overloading Operator <<

Hi, I'm having some trouble overloading the << operator. I have the
following, very simple code:

#include <iostream>
using namespace std;

class test
{
private:
int val;
public:
test():val(0){}
const int GetVal() const{
return val;
}

ostream& operator<< (ostream& os , test& a) {
os << a.GetVal();
return os;
}
};
//------End Sample Code

I get the following error during compile. What does this error mean?

error: 'std::ostream& test::operator<<(std::ostream&, test&)' must
take exactly one argument

I want to do something like

test MyTest;
cout << test << endl;

Thanks

Sep 16 '05 #1
8 8350

jois.de.vivre wrote:
Hi, I'm having some trouble overloading the << operator. I have the
following, very simple code:

#include <iostream>
using namespace std;

class test
{
private:
int val;
public:
test():val(0){}
const int GetVal() const{
return val;
}

ostream& operator<< (ostream& os , test& a) {
os << a.GetVal();
return os;
}
};
//------End Sample Code

I get the following error during compile. What does this error mean?

error: 'std::ostream& test::operator<<(std::ostream&, test&)' must
take exactly one argument


operator<< can either be a member function and take one argument - an
ostream& - or it can be a nonmember function and take two arguments -
an ostream& and a const test&. You conflate the two - you both make it
a member function, but you also include two arguments. Hence the error
message. Choose one or the other. And typically people make it a
nonmember function, and I suggest you do the same.

By the way, make it const test&, not test&.

Best regards,

Tom

Sep 16 '05 #2
Ian
jo***********@gmail.com wrote:

ostream& operator<< (ostream& os , test& a) {
os << a.GetVal();
return os;
}
};
//------End Sample Code

I get the following error during compile. What does this error mean?

error: 'std::ostream& test::operator<<(std::ostream&, test&)' must
take exactly one argument

It means the member operator<< must have one argument.

try

friend std::ostream& operator<<( std::ostream& os, const test& a)
{
os << a.GetVal();
return os;
}

Or if no private members are accessed, put the operator outside of the
class.

Ian
Sep 17 '05 #3
"Thomas Tutone" <Th***********@yahoo.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...

jois.de.vivre wrote:
Hi, I'm having some trouble overloading the << operator. I have the
following, very simple code:

#include <iostream>
using namespace std;

class test
{
private:
int val;
public:
test():val(0){}
const int GetVal() const{
return val;
}

ostream& operator<< (ostream& os , test& a) {
os << a.GetVal();
return os;
}
};
//------End Sample Code

I get the following error during compile. What does this error mean?

error: 'std::ostream& test::operator<<(std::ostream&, test&)' must
take exactly one argument


operator<< can either be a member function and take one argument - an
ostream& - or it can be a nonmember function and take two arguments -
an ostream& and a const test&. You conflate the two - you both make it
a member function, but you also include two arguments. Hence the error
message. Choose one or the other. And typically people make it a
nonmember function, and I suggest you do the same.


Well, OP is probably trying to use it in this usual context:

test my_test;
cout << my_test;

In that case, operator<< must be a free function and take two arguments.

Also, regarding Ian's post, if needed, the 'friend' keyword goes with the
in-class declaration of the free function; not with the definition of it:

class test
{
friend ostream & operator<< (ostream &, test const &);

/* ... */
};

ostream & operator<< (ostream & os, test const & object)
{
return os << object.val;
}

Of course, since private access is not needed in the OP's case, it is better
to just define the free function:

class test
{
/* ... */
};

ostream & operator<< (ostream & os, test const & object)
{
return os << object.GetVal();
}

Ali

Sep 17 '05 #4
Thomas Tutone <Th***********@yahoo.com> wrote:
operator<< can either be a member function and take one argument - an
ostream& - or it can be a nonmember function and take two arguments -
an ostream& and a const test&. You conflate the two - you both make it
a member function, but you also include two arguments. Hence the error
message. Choose one or the other. And typically people make it a
nonmember function, and I suggest you do the same.


I looked in the FAQ and did not find the answer to this question:

Why are the nonmember function versions preferred over the member
function versions?

--
Marcus Kwok
Sep 29 '05 #5
Marcus Kwok wrote:
Thomas Tutone <Th***********@yahoo.com> wrote:
operator<< can either be a member function and take one argument - an
ostream& - or it can be a nonmember function and take two arguments -
an ostream& and a const test&. You conflate the two - you both make it
a member function, but you also include two arguments. Hence the error
message. Choose one or the other. And typically people make it a
nonmember function, and I suggest you do the same.

I looked in the FAQ and did not find the answer to this question:

Why are the nonmember function versions preferred over the member
function versions?


If you are trying to output _your_ class to an ostream object using
operator << (insertion into stream), then you simply *can't* have your
overloaded operator as a member because it has to be a member of the
'ostream', and you're not allowed to modify it. You're stuck with
implementing operator<< as non-member.

Now, as to why sometimes implementing two-operand operators is better
as non-member than a member, it's covered in Effective C++ book. And
you can only consider the reasons if you have a choice. In your case
you don't.

V
Sep 29 '05 #6
Victor Bazarov <v.********@comacast.net> wrote:
Marcus Kwok wrote:
Thomas Tutone <Th***********@yahoo.com> wrote:
operator<< can either be a member function and take one argument - an
ostream& - or it can be a nonmember function and take two arguments -
an ostream& and a const test&. You conflate the two - you both make it
a member function, but you also include two arguments. Hence the error
message. Choose one or the other. And typically people make it a
nonmember function, and I suggest you do the same.

I looked in the FAQ and did not find the answer to this question:

Why are the nonmember function versions preferred over the member
function versions?


If you are trying to output _your_ class to an ostream object using
operator << (insertion into stream), then you simply *can't* have your
overloaded operator as a member because it has to be a member of the
'ostream', and you're not allowed to modify it. You're stuck with
implementing operator<< as non-member.


Doesn't this contradict Thomas's first sentence above? What about the
member function

ostream& MyClass::operator<<(ostream&);
Will this not allow you to do, for example,

MyClass c;
std::cout << c;
or does the declaration imply

c << std::cout;
(which is backwards from the way it's supposed to be)?
Now, as to why sometimes implementing two-operand operators is better
as non-member than a member, it's covered in Effective C++ book. And
you can only consider the reasons if you have a choice. In your case
you don't.


Thanks, I'll look into picking up that book; it seems to be very well
regarded.

--
Marcus Kwok
Sep 29 '05 #7
Marcus Kwok wrote:
Victor Bazarov <v.********@comacast.net> wrote:
Marcus Kwok wrote:
Thomas Tutone <Th***********@yahoo.com> wrote:
operator<< can either be a member function and take one argument - an
ostream& - or it can be a nonmember function and take two arguments -
an ostream& and a const test&. You conflate the two - you both make it
a member function, but you also include two arguments. Hence the error
message. Choose one or the other. And typically people make it a
nonmember function, and I suggest you do the same.
I looked in the FAQ and did not find the answer to this question:

Why are the nonmember function versions preferred over the member
function versions?
If you are trying to output _your_ class to an ostream object using
operator << (insertion into stream), then you simply *can't* have your
overloaded operator as a member because it has to be a member of the
'ostream', and you're not allowed to modify it. You're stuck with
implementing operator<< as non-member.

Doesn't this contradict Thomas's first sentence above? What about the
member function

ostream& MyClass::operator<<(ostream&);
Will this not allow you to do, for example,

MyClass c;
std::cout << c;


No. It would allow you to do this

MyClass c;
c << std::cout;
or does the declaration imply

c << std::cout;
(which is backwards from the way it's supposed to be)?


Yes. Well, it's not backwards. The left operand of a binary member is
always the object of the class in which the operand is the member. You
could, for fun, define it as

ostream& MyClass::operator>>(ostream&);

and use it as

MyClass c;
c >> std::cout << std::endl;

A bit awkward, but some may find it making sense...

V
Sep 29 '05 #8
Victor Bazarov <v.********@comacast.net> wrote:
Marcus Kwok wrote:
ostream& MyClass::operator<<(ostream&);
Will this not allow you to do, for example,

MyClass c;
std::cout << c;
No. It would allow you to do this

MyClass c;
c << std::cout;
or does the declaration imply

c << std::cout;
(which is backwards from the way it's supposed to be)?


Yes. Well, it's not backwards. The left operand of a binary member is
always the object of the class in which the operand is the member.


OK, I understand. Thanks.
You could, for fun, define it as

ostream& MyClass::operator>>(ostream&);

and use it as

MyClass c;
c >> std::cout << std::endl;

A bit awkward, but some may find it making sense...


Maybe it will be useful when they start an Obfuscated C++ contest
(IOC++CC?) :)

--
Marcus Kwok
Sep 29 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: gipsy boy | last post by:
I made a Stack structure, as an exercise on templates. Stack ll; Is this used irl? : "ll << o" to push an object pointer to the end of the list and "ll >> &o" to push it off and save the address...
10
by: pmatos | last post by:
Hi all, I have the following code: class test { public: test(const std::string *n) : name(n) {} virtual ~test() {} const std::string * getName() { return name; }
2
by: pmatos | last post by:
Hi all, I'm overloading operator<< for a lot of classes. The question is about style. I define in each class header the prototype of the overloading as a friend. Now, where should I define the...
25
by: Steve Richter | last post by:
is it possible to overload the << operator in c# similar to the way it is done in c++ ? MyTable table = new MyTable( ) ; MyTableRow row = new MyTableRow( ) ; row << new MyTableCell( "cell1 text...
4
by: spibou | last post by:
I saw it at http://www.faqs.org/rfcs/rfc1305.html Is it not the same as writing ``if (m)'' ?
6
by: iLL | last post by:
Okay, I’m just a little confused on exactly what the system is doing when I say: #include <iostream> class test { private: int i; public:
1
by: Sunny | last post by:
The way to overload operator << is : ostream& operator << (ostream& os, const Obj& obj); and this is a member function. My question is why do we need to provide a const reference of Obj as...
1
by: buburuz | last post by:
Hi, I have a question about overloading operator<< . Actually I am trying to understand how it works when chaining multiple calls to this operator. I have a very simple class (MyOut) with an...
6
by: Rob McDonald | last post by:
I would like to force all the classes in my hierarchy to implement the << operator for testing purposes. My base class is a pure virtual class. I started out by working with operator...
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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...
1
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
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...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.