10.3. Writing Your Own Stream Manipulators
Problem
You need a stream manipulator that does something the standard ones can’t. Or, you want to have a single manipulator set several flags on the stream instead of calling a set of manipulators each time you want a particular format.
Solution
To write a manipulator that doesn’t take an argument (à la left), write a function that takes an ios_base parameter and sets stream flags on it. If you need a manipulator
that takes an argument, see the discussion a little later. Example 10-4 shows how to write a manipulator
that doesn’t take an argument.
Example 10-4. A simple stream manipulator
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
// make floating-point output look normal
inline ios_base& floatnormal(ios_base& io) {
io.setf(0, ios_base::floatfield);
return(io);
}
int main() {
ios_base::fmtflags flags = // Save old flags
cout.flags();
double pi = 22.0/7.0;
cout << "pi = " << scientific // Scientific mode
<< pi * 1000 << '\n';
cout << "pi = " << floatnormal
<< pi << '\n';
cout.flags(flags);
}Discussion
There are two kinds of manipulators: those that accept arguments and those that don’t. Manipulators that take no arguments are easy to write. All you have to do is write a function that accepts a stream parameter, does something to it (sets a flag or changes a setting), and returns it. Writing a manipulator that takes one or more arguments is more complicated because you need to create additional classes and functions ...