Connecting Tech Pros Worldwide Forums | Help | Site Map

Overloading Operator <<

jois.de.vivre@gmail.com
Guest
 
Posts: n/a
#1: Sep 17 '05
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


Thomas Tutone
Guest
 
Posts: n/a
#2: Sep 17 '05

re: Overloading Operator <<



jois.de.vivre wrote:
[color=blue]
> 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[/color]

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

Ian
Guest
 
Posts: n/a
#3: Sep 17 '05

re: Overloading Operator <<


jois.de.vivre@gmail.com wrote:[color=blue]
>
> 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
>[/color]
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
Ali Çehreli
Guest
 
Posts: n/a
#4: Sep 17 '05

re: Overloading Operator <<


"Thomas Tutone" <Thomas8675309@yahoo.com> wrote in message
news:1126913426.222002.323080@g49g2000cwa.googlegr oups.com...[color=blue]
>
> jois.de.vivre wrote:
>[color=green]
>> 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[/color]
>
> 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.[/color]

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

Marcus Kwok
Guest
 
Posts: n/a
#5: Sep 29 '05

re: Overloading Operator <<


Thomas Tutone <Thomas8675309@yahoo.com> wrote:[color=blue]
> 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.[/color]

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
Victor Bazarov
Guest
 
Posts: n/a
#6: Sep 29 '05

re: Overloading Operator <<


Marcus Kwok wrote:[color=blue]
> Thomas Tutone <Thomas8675309@yahoo.com> wrote:
>[color=green]
>>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.[/color]
>
>
> 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?[/color]

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
Marcus Kwok
Guest
 
Posts: n/a
#7: Sep 29 '05

re: Overloading Operator <<


Victor Bazarov <v.Abazarov@comacast.net> wrote:[color=blue]
> Marcus Kwok wrote:[color=green]
>> Thomas Tutone <Thomas8675309@yahoo.com> wrote:
>>[color=darkred]
>>>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.[/color]
>>
>>
>> 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?[/color]
>
> 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.[/color]

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)?
[color=blue]
> 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.[/color]

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

--
Marcus Kwok
Victor Bazarov
Guest
 
Posts: n/a
#8: Sep 29 '05

re: Overloading Operator <<


Marcus Kwok wrote:[color=blue]
> Victor Bazarov <v.Abazarov@comacast.net> wrote:
>[color=green]
>>Marcus Kwok wrote:
>>[color=darkred]
>>>Thomas Tutone <Thomas8675309@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?[/color]
>>
>>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.[/color]
>
>
> 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;[/color]

No. It would allow you to do this

MyClass c;
c << std::cout;
[color=blue]
> or does the declaration imply
>
> c << std::cout;
> (which is backwards from the way it's supposed to be)?[/color]

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
Marcus Kwok
Guest
 
Posts: n/a
#9: Sep 29 '05

re: Overloading Operator <<


Victor Bazarov <v.Abazarov@comacast.net> wrote:[color=blue]
> Marcus Kwok wrote:[color=green]
>> ostream& MyClass::operator<<(ostream&);
>>
>>
>> Will this not allow you to do, for example,
>>
>> MyClass c;
>> std::cout << c;[/color]
>
> No. It would allow you to do this
>
> MyClass c;
> c << std::cout;
>[color=green]
>> or does the declaration imply
>>
>> c << std::cout;
>> (which is backwards from the way it's supposed to be)?[/color]
>
> 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.[/color]

OK, I understand. Thanks.
[color=blue]
> 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...[/color]

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

--
Marcus Kwok
Closed Thread