overloaded ops << and >>

J

jalkadir

I have a class that overloads the inserter and the extractor operators,
but there is a problem with the way I worte the methods; because the
compiler does not like it at all.
This is the snip of what the problem looks like:

--- money.hpp
friend std::eek:stream& std::eek:perator<<( std::eek:stream&, const jme::Money&
); friend std::istream& std::eek:perator>>( std::istream&,
jme::Money& );

--- money.cpp
std::eek:stream&
std::eek:perator<<( std::eek:stream& os, const jme::Money& obj ) {
os << obj.getAmount();
return os;
}

std::istream&
std::eek:perator>>( std::istream& is, jme::Money& obj ) {
is >> obj.amount;
return is;
}

--- error
In file included from money.cpp:2:
money.hpp:67: error: `std::eek:stream& std::eek:perator<<(std::eek:stream&,
const jme::Money&)' should have been declared inside `std'
money.hpp:68: error: `std::istream& std::eek:perator>>(std::istream&,
jme::Money&)' should have been declared inside `std'

What am I doing wrong?
Can anybody help?

TIA
 
V

Victor Bazarov

jalkadir said:
I have a class that overloads the inserter and the extractor operators,
but there is a problem with the way I worte the methods; because the
compiler does not like it at all.
This is the snip of what the problem looks like:

--- money.hpp
friend std::eek:stream& std::eek:perator<<( std::eek:stream&, const jme::Money&

Drop the 'std::' in front of the "operator" keyword. In all places.
 
J

jalkadir

Thanks for the help, I am very thankful for it.
I did as you suggested, but after the changes I get another error
message. Let me explain: this is what the new changes look like:
std::eek:stream&
operator<<( std::eek:stream& os, const jme::Money& obj ) {
os << obj.getAmount();
return os;
}
std::istream&
operator>>( std::istream& is, jme::Money& obj ) {
is >> obj.amount;
return is;
}

and this is the error I am getting:
In file included from main.cpp:2:
money.hpp:67: error: `std::eek:stream& std::eek:perator<<(std::eek:stream&,
const jme::Money&)' should have been declared inside `std'
money.hpp:68: error: `std::istream& std::eek:perator>>(std::istream&,
jme::Money&)' should have been declared inside `std'


Again, thanks for the help!!
 
V

Victor Bazarov

jalkadir said:
Thanks for the help, I am very thankful for it.
I did as you suggested, but after the changes I get another error
message. Let me explain: this is what the new changes look like:
std::eek:stream&
operator<<( std::eek:stream& os, const jme::Money& obj ) {
os << obj.getAmount();
return os;
}
std::istream&
operator>>( std::istream& is, jme::Money& obj ) {
is >> obj.amount;
return is;
}

and this is the error I am getting:
In file included from main.cpp:2:
money.hpp:67: error: `std::eek:stream& std::eek:perator<<(std::eek:stream&,
const jme::Money&)' should have been declared inside `std'
money.hpp:68: error: `std::istream& std::eek:perator>>(std::istream&,
jme::Money&)' should have been declared inside `std'

You say you're getting "another" error message. How are these two
different from what you got before? I can't find any difference.

Are you sure you replaced _all_ "std::eek:perator<<" with "operator<<"?

V
 
J

jalkadir

Howly mowly!!
Yes, I am giving you the wrong info. Sorry about that. :(
OK, here is what the new error looks like:

--- Error
money.hpp: In function `std::istream& operator>>(std::istream&,
jme::Money&)':
money.hpp:22: error: `float jme::Money::amount' is protected
money.cpp:85: error: within this context

--- Source Code
std::eek:stream&
operator<<( std::eek:stream& os, const jme::Money& obj ) {
return os << obj.getAmount();
//return os;
}
std::istream&
operator>>( std::istream& is, jme::Money& obj ) {
is >> obj.amount;
return is;
}

--- Header Code
namespace jme{
class Money{
protected: float amount;
........
public:
friend std::eek:stream& operator<<( std::eek:stream&, const
jme::Money& );
friend std::istream& operator>>( std::istream&, jme::Money&
);
 
V

Victor Bazarov

jalkadir said:
Howly mowly!!
Yes, I am giving you the wrong info. Sorry about that. :(
OK, here is what the new error looks like:

--- Error
money.hpp: In function `std::istream& operator>>(std::istream&,
jme::Money&)':
money.hpp:22: error: `float jme::Money::amount' is protected
money.cpp:85: error: within this context

--- Source Code
std::eek:stream&
operator<<( std::eek:stream& os, const jme::Money& obj ) {
return os << obj.getAmount();
//return os;
}
std::istream&
operator>>( std::istream& is, jme::Money& obj ) {
is >> obj.amount;
return is;
}

--- Header Code
namespace jme{
class Money{
protected: float amount;
........
public:
friend std::eek:stream& operator<<( std::eek:stream&, const
jme::Money& );
friend std::istream& operator>>( std::istream&, jme::Money&
);

Yes, this is true. However, it seems that your compiler doesn't want to
pick up the 'friend' declaration. Try changing the 'friend' declarations
to

friend std::eek:stream& ::eek:perator<<( .. );
friend std::istream& ::eek:perator>>( .. );

(notice the '::' in front of the 'operator' keyword).

And if you declare those functions before the class definition, it would
not hurt.

V
 
J

jalkadir

That would tell the compiler that the 'operator' I am talking about
would be the one belonging to the 'std', right? Which means that my
previous statement (std::eek:perator<<) is the same as ::eek:perator<<(...),
yes?

Let me see what happens, back in a bit!
 
V

Victor Bazarov

jalkadir said:
That would tell the compiler that the 'operator' I am talking about
would be the one belonging to the 'std', right? Which means that my
previous statement (std::eek:perator<<) is the same as ::eek:perator<<(...),
yes?
No.

Let me see what happens, back in a bit!

K. TTYL

V
 
J

jalkadir

I am sorry Victor, I thought it ment the same thing. What does it
mean? if you don't mind my question.

On another front, here is the latest incarnation of my inserters and
extractors:

friend std::eek:stream& operator<<( std::eek:stream&, const jme::Money& );
friend std::istream& operator>>( std::istream&, jme::Money& );


std::eek:stream&
operator<<( std::eek:stream& os, const jme::Money& obj ) {
std::cout << "Check this out" << std::endl;
return os << obj.getAmount();
//return os;
}
std::istream&
operator>>( std::istream& is, jme::Money& obj ) {
float tmp;
is >> tmp;
std::cout << LINE << " " << FILE << " " << tmp << std::endl;
obj.setAmount(tmp);
return is;
}

I would expect that the statement

jme::Money money("12.21");
std::cout << " Value is: " << money << std::endl;

would display 12.21, but in instead it displays 0x4c1094 !?

I am really going *loco* with this part of the program. It just does
not make sence.

Can you help?
 
V

Victor Bazarov

jalkadir said:
I am sorry Victor, I thought it ment the same thing. What does it
mean? if you don't mind my question.

The absence of any scope resolution operator in front of the name
means probably "the nearest enclosing namespace", in your case 'jme'.
If you put '::' without anything before it, it will mean "global
namespace". What book are you reading that doesn't mention the
global namespace?

On another front, here is the latest incarnation of my inserters and
extractors:

friend std::eek:stream& operator<<( std::eek:stream&, const jme::Money& );
friend std::istream& operator>>( std::istream&, jme::Money& );


std::eek:stream&
operator<<( std::eek:stream& os, const jme::Money& obj ) {
std::cout << "Check this out" << std::endl;
return os << obj.getAmount();
//return os;
}
std::istream&
operator>>( std::istream& is, jme::Money& obj ) {
float tmp;
is >> tmp;
std::cout << LINE << " " << FILE << " " << tmp << std::endl;
obj.setAmount(tmp);
return is;
}

I would expect that the statement

jme::Money money("12.21");
std::cout << " Value is: " << money << std::endl;

would display 12.21, but in instead it displays 0x4c1094 !?

I am really going *loco* with this part of the program. It just does
not make sence.

Well, it seems that you have a conversion operator defined in your
'jme::Money' class, which probably gives you 'void*' which the <<
operator outputs as a number.

Eliminate all extraneous things, make your program as simple as you
can, and post it _complete_. With all the bits and pieces of the
changing program I cannot make heads or tails of it.

V
 
O

Old Wolf

jalkadir said:
--- Error
money.hpp: In function `std::istream& operator>>(std::istream&,
jme::Money&)':
money.hpp:22: error: `float jme::Money::amount' is protected
money.cpp:85: error: within this context

std::eek:stream&
operator<<( std::eek:stream& os, const jme::Money& obj ) {
return os << obj.getAmount();
}
std::istream&
operator>>( std::istream& is, jme::Money& obj ) {
is >> obj.amount;
return is;
}

These functions are in the global namespace.
But they should be in the jme namespace.
Because of argument-dependent lookup (introduced in the C++
standard), a statement like:

is >> obj;

will only search for operator>> in the namespaces of 'is'
and 'obj' (ie. 'std' and 'jme'), and NOT in the global namespace.

Your declarations must look like this:

namespace jme
{
std::eek:stream&
operator<<( std::eek:stream& os, const jme::Money& obj );

std::istream&
operator>>( std::istream& is, jme::Money& obj );
};

The definitions can either look like that, or like:

std::eek:stream& jme::eek:perator<<
( std::eek:stream& os, const jme::Money& obj )
{
return os << obj.getAmount();
}
--- Header Code
namespace jme{
class Money{
protected: float amount;
........
public:
friend std::eek:stream& operator<<( std::eek:stream&, const
jme::Money& );
friend std::istream& operator>>( std::istream&, jme::Money&
);

I'm not an expert on 'friend', but I think you need to declare
these operator<< and operator>> BEFORE the friend declarations.

Also, some compilers (eg. MSVC 6.0) have bugs and won't let you
do this, even if you get it right.
 

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,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top