TITLE: Customizing IO manipulators (part I of III) PROBLEM: weber@nashua.hp.com (John Weber) Sorry if this has been discussed before, but I couldn't find it in the FAQ. Is there a generally accepted means of defining new manipulators for iostreams. I have defined a class that I would like to control the output format for using a manipulator specific to that class, but I'm not sure how to go about it. Its seems the predefined manipulators set attributes on the iostream object itself, but its not clear to me how I can extend this paradigm for user defined things. RESPONSE: kanze@us-es.sel.de (James Kanze), 3 Aug 94 First, the manipulator must communicate with the insertion function (operator>>). This will take place through data in the ios class (the base class for all iostreams). Ios already defines a certain number of flags and parameters which can be set and read from the outside. Flags (use setf, unsetf to manipulate), width, precision and fill are the ones used for formatting. If these are not enough, you can always get more; ios contains an infinite large array, and all you have to do is allocate a word in it for your use. The function ios::xalloc() will return a unique integer each time it is called; use this to avoid conflicts. Thus, to acquire a new flag word: static int myFlagsIndex = -1 ; // Visible to both the manip. // and operator>>. // To get a reference to your flags: if ( myFlagsIndex < 0 ) myFlagsIndex = ios::xalloc() ; long& myFlags = stream.iword( myFlagsIndex ) ; If your manipulator doesn't require parameters, the job is simple: just declare it as a function with the following signature: ios& myManip( ios& stream ) { // Set the flag bits... return stream ; } If you need parameters, then the job is somewhat more complicated, and you will in fact need two functions and a class for each manipulator. If one parameter is sufficient, then have a look at iomanip.h (where setw, et al. are declared). This contains the generic class SMANIP (or maybe the template class smanip on newer implementations), which will generate the class automatically for you. Anyhow: - The class will be defined to have a constructor which takes the arguments of the manipulator and saves them. If you need several manipulators with the same arguments, they can use the same class if the class also requires and stores a pointer to function parameter. (This is what SMANIP does.) - The manipulator itself (what the user sees) will simply return an instance of this class. For example, if SMANIP(int) is used for the class: SMANIP(int) myManip( int arg ) { return SMANIP(int)( myManipFnc , arg ) ; } In this case, myManipFnc (the second function, see below) is passed as a parameter, since other manipulators (setw, for example) also return an SMANIP. - The second function looks as follows: ios& myManipFnc( ios& stream , int arg ) { // Set the flags in stream using arg. return stream ; } - Finally, if you write your own class (because you need more than one parameter, for example), you will have to declare and define operator>> as a friend of the class. This operator does nothing but call your function; a glance at the inline code in iomanip should show you all that is necessary. (Frankly, I would avoid manipulators with more than one parameter; in this case, you don't have to worry about the class or operator>>.)