This is a exercise for school, so please provide just hints and no 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 have to write a manipulator with the form ios_base& my_manip(basic_ios&)
.
If I use it like this (without using return value):
toggle(cout);
... that works fine. But if I use it like that:
toggle(cout) << 54444.6456555 << endl;
That does not work (Because std::ios_base does not have operator<<() as stated below).
In general I do not get what ios_base& my_manip(basic_ios&)
could be useful for... Do you have a hint/example?
You guys already helped me a lot! What I still do NOT understand, is the motivation to pass a basic_ios
and give back ios_base
(because that is suggested to do in the exercise I have to solve...). What could be a possible scenario to use this???
The problem with the manipulator is that it returns an std::ios_base&
rather than a std::ostream&
you can write to. You could change the manipulator to take an std::ostream&
as parameter and return the reference received. However, the output stream class defines output operators which take pointers to functions:
std::ostream& std::ostream::operator<< (std::ios_base& (*)(std::ios_base&)) { ... }
That is, you can just insert manipulators pretty much the way you would do it with, e.g., std::hex
:
std::cout << std::hex << 123 << ' ' << std::dec << 123 << '\n';
In addition to the issue which Dietmar addressed: io.flags()
& ios::scientific
does not return a bool
, and the conversion
to bool
probably doesn't 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 being part of a variable with a type named ...flags
,
floatfield
is not a flag, but a field which can take on at
least three values: fixed
, scientific
and its default value
in which neither of these are set. (basefield
and
adjustfield
behave similarly.)
Note too the use of the two argument form of ios::setf
; it is
designed especially for these bitfield format parameters, and
resets the bits in its second argument before setting the ones
in its first.
I might add that you probably do not want to call io.flags
in your manipulator; this sets all of the formatting flags to
the value you give, effectively resetting all other formatting
flags. If you're only outputting floating point, this may not
be a problem (although showpos
, showpoint
, uppercase
and
possibly unitbuf
might be relevant), but you never know.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With