User-defined manipulators

D

David W

A colleague wants to do this with a std::eek:stream:

os << fahrenheit << 37.0;

This would output 98.6 (i.e., Celsius --> Fahrenheit).

I've already suggested os << fahrenheit(37.0), but he doesn't like it.

Then he suggested that the function taking the stream and fahrenheit manipulator
could return an instance of another user-defined type, to which the 37.0 is then
passed to do the conversion and output. This would work, but you might want to
pass something else, such as another manipulator, before the value (use a
catch-all member template maybe?).

Any other ideas?

DW
 
S

Sarath

A colleague wants to do this with a std::eek:stream:

os << fahrenheit << 37.0;

This would output 98.6 (i.e., Celsius --> Fahrenheit).

I've already suggested os << fahrenheit(37.0), but he doesn't like it.

Then he suggested that the function taking the stream and fahrenheit manipulator
could return an instance of another user-defined type, to which the 37.0 is then
passed to do the conversion and output. This would work, but you might want to
pass something else, such as another manipulator, before the value (use a
catch-all member template maybe?).

Any other ideas?

DW

Are you trying to redefine the meaning of operator <<? It is having an
associativity L->R. You may seek help of parenthesis to redifine the
meaning of operator.
e.g You may have to write like this after writing proper functions.
cout<<(f<<10);

Regards,
Sarath
http://sarathc.wordpress.com/
 
D

David W

Sarath said:
Are you trying to redefine the meaning of operator <<?

Not at all. You can already have, for example, os << std::setprecision(2) <<
std::setw(6) << 37.0;
'fahrenheit' would merely be an additional, user-defined, member of the family
to which setprecision and setw belong.
It is having an
associativity L->R. You may seek help of parenthesis to redifine the
meaning of operator.
e.g You may have to write like this after writing proper functions.
cout<<(f<<10);

DW
 
J

Jim Langston

David W said:
Not at all. You can already have, for example, os << std::setprecision(2)
<< std::setw(6) << 37.0;
'fahrenheit' would merely be an additional, user-defined, member of the
family to which setprecision and setw belong.

Not that easy. I was playing around to see if I could figure it out. There
might be a way, but setw actually just calls a function in io_base to set
the hex then returns io_base. It actually doesn't process anythign
following.
 
D

David W

Jim Langston said:
Not that easy. I was playing around to see if I could figure it out. There
might be a way, but setw actually just calls a function in io_base to set the
hex then returns io_base.

hex for setw?
It actually doesn't process anythign following.

Yes, that's the problem. The std:: manipulators alter the internal state of the
stream.

DW
 
D

David Harmon

On Thu, 22 Mar 2007 11:36:15 +1100 in comp.lang.c++, "David W"
A colleague wants to do this with a std::eek:stream:

os << fahrenheit << 37.0;

This would output 98.6 (i.e., Celsius --> Fahrenheit).

I've already suggested os << fahrenheit(37.0), but he doesn't like it.

You are right. He is wrong.

What, does he want every possible conversion formula to be remembered
inside iostreams? And does he want all the subsequent numerical output
to get scaled by some factor set by some code long ago and far away?
 
W

weihan

A colleague wants to do this with a std::eek:stream:

os << fahrenheit << 37.0;

This would output 98.6 (i.e., Celsius --> Fahrenheit).

I've already suggested os << fahrenheit(37.0), but he doesn't like it.

Then he suggested that the function taking the stream and fahrenheit manipulator
could return an instance of another user-defined type, to which the 37.0 is then
passed to do the conversion and output. This would work, but you might want to
pass something else, such as another manipulator, before the value (use a
catch-all member template maybe?).

Any other ideas?

DW


Try this :

struct Fahrenheit {

ostream *fout ;

friend Fahrenheit& operator<< ( ostream& out , Fahrenheit& foo )
{
foo.fout = &out ;
return foo ;
}

};

ostream& operator<< ( const Fahrenheit& foo , double s ) {
return *(foo.fout) << 9*s/5+32 ;
}


Fahrenheit& operator<< ( Fahrenheit& foo , _Setw s ) {
foo.fout->width(s._M_n) ;
return foo ;
}


int main() {

Fahrenheit fahrenheit ;
int temp ;

for ( temp = 0 ; temp <= 100 ; temp+=10 )
cout << "C : " << setw(3) << temp << " --> F : "
<< fahrenheit << setw(3) << temp << endl ;

return 0 ;

}
 
D

David W

David Harmon said:
On Thu, 22 Mar 2007 11:36:15 +1100 in comp.lang.c++, "David W"


You are right. He is wrong.

He says that the form he prefers is more readable.
What, does he want every possible conversion formula to be remembered
inside iostreams?

I don't think any of them can be remembered inside iostreams. That's why I asked
if anyone had another idea. If there is another way, then maybe you could have
every possible conversion.
And does he want all the subsequent numerical output
to get scaled by some factor set by some code long ago and far away?

He probably wants it to work the same way as setw, which is only in effect for
the next insertion.

DW
 
D

David W

A colleague wants to do this with a std::eek:stream:

os << fahrenheit << 37.0;

This would output 98.6 (i.e., Celsius --> Fahrenheit).

I've already suggested os << fahrenheit(37.0), but he doesn't like it.

Then he suggested that the function taking the stream and fahrenheit
manipulator
could return an instance of another user-defined type, to which the 37.0 is
then
passed to do the conversion and output. This would work, but you might want to
pass something else, such as another manipulator, before the value (use a
catch-all member template maybe?).

Any other ideas?


Try this :

struct Fahrenheit {

ostream *fout ;

friend Fahrenheit& operator<< ( ostream& out , Fahrenheit& foo )
{
foo.fout = &out ;
return foo ;
}

};

ostream& operator<< ( const Fahrenheit& foo , double s ) {
return *(foo.fout) << 9*s/5+32 ;
}


Fahrenheit& operator<< ( Fahrenheit& foo , _Setw s ) {
foo.fout->width(s._M_n) ;
return foo ;
}


int main() {

Fahrenheit fahrenheit ;
int temp ;

for ( temp = 0 ; temp <= 100 ; temp+=10 )
cout << "C : " << setw(3) << temp << " --> F : "
<< fahrenheit << setw(3) << temp << endl ;

return 0 ;

}

Yes, that would work. The other manipulators would have to be included, though,
as well as anything else that's possible before the value is inserted (if there
is anything). It also wouldn't cater for manipulators that might be added in
future versions of the library. Still, he might have to live with something
that's not perfect (or go with my much simpler idea).

DW
 

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

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top