How to use this manipulator

This is an exercise for the school, so please provide only tips and complete examples; -)

I have my own manipulator:

template<typename T, typename Tr=char_traits<T> > ios_base& toggle(basic_ios<T,Tr>& io) { if(io.flags() & ios::scientific) { io.unsetf(ios::scientific); io.flags(ios::fixed); } else { io.unsetf(ios::fixed); io.flags(ios::scientific); } return io; } 

I wrote this because I need to write a manipulator with the form ios_base& my_manip(basic_ios&) .

If I use it like this (without using the return value):

 toggle(cout); 

... it works great. But if I use it like this:

 toggle(cout) << 54444.6456555 << endl; 

This does not work (since std :: ios_base does not have a <<() operator, as indicated below).

In general, I do not understand that ios_base& my_manip(basic_ios&) may be useful for ... Do you have a hint / example?


You guys have helped me a lot! What I still DO NOT understand is the motivation to pass basic_ios and return ios_base (because it is proposed to do this in an exercise that I have to solve ...). What could be a possible scenario for using this?

+6
source share
2 answers

The problem with the manipulator is that it returns std::ios_base& , not std::ostream& , which you can write to. You can change the manipulator to take the std::ostream& as parameter and return the resulting link. However, the class of the output stream defines output operators that accept pointers to functions:

 std::ostream& std::ostream::operator<< (std::ios_base& (*)(std::ios_base&)) { ... } 

That is, you can simply embed the manipulators almost the way you did, for example, std::hex :

 std::cout << std::hex << 123 << ' ' << std::dec << 123 << '\n'; 
+4
source

In addition to the problem that Dietmar addressed: io.flags() & ios::scientific does not return bool , and converting to bool probably does not do what you want. You need something along the lines of:

 if ( (io.flags() & ios::floatfield) == ios::fixed ) { io.setf( ios::scientific, ios::floatfield ); } else if ( (io.flags() & ios::floatfield) == ios::scientific ) { io.setf( ios::fixed, ios::floatfield ); } else { // Whatever you want to happen first time around... } 

Despite the fact that it is part of a variable with type ...flags , a floatfield not a flag, but a field that can take at least three values: fixed , scientific and the default value in which none of them are set. ( basefield and adjustfield behave similarly.)

Also note the use of the two forms of the ios::setf argument; it is special for these bitfield format parameters, and resets the bit in the second argument before setting in its first.

I can add that you probably do not want to call io.flags in your manipulator; this sets all formatting flags to the value you give, effectively dropping all other formatting flags. If you only print floating points, it may not (although showpos , showpoint , uppercase and maybe unitbuf might be relevant), but you never know.

+2
source

All Articles