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 | | | | 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 | | | | 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 | | | | 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 | | | | 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 | | | | 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 | | | | 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 | | | | 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 | | | | 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 |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,449 network members.
|