Writing Your Own Stream Manipulators

Writing Your Own Stream Manipulators

We’ve seen several stream manipulators such as endl, setw(int), etc.  Maybe you would like to implement your own stream manipulators, or you don’t like the ones provided, and you’d like to produce a more consistent interface of your own…

There are two cases:

  • Stream manipulators without arguments, and:
  • Stream manipulators with arguments

Stream Manipulators without Arguments

This is much the simpler of the two cases.

A stream manipulator without arguments is a function that accepts a reference to a stream, and returns that reference.

For example, a stream manipulator that inserts a tab into an output stream might look like:

ostream& tab(ostream& out)
{
	return out << '\t';
}

Questions:

What are the types of operands in the following expression?

cout << tab

What kind of operator << must be provided in order for this to work?

Answers:

The types of the operands of the expression 

cout << tab

are:

  • ostream
  • ostream &(*)(ostream &)

Huh? Come again?  What’s that second one?

Let’s write a typedef to make it a little clearer:

typedef ostream &(*Omanip)(ostream &);

So the operator << we need is:

ostream &ostream::operator<<(Omanip m)
{
  return (*m)(*this);
}

Got that? This operator is supplied in the iostream header file, and allows the manipulator to act on itself…

Example:

//
//  tab.h
//  iostreams - Stream Manipulator functions
//
//  Created by Bryan Higgs on 9/4/24.
//

#ifndef tab_h
#define tab_h

#include <iostream>

inline std::ostream& tab(std::ostream& out)
{
  return out << '\t';
}

#endif /* tab_h */

Here’s a simple program to test the tab Stream Manipulator function:

//
//  main.cpp
//  iostreams - Stream Manipulator functions
//
//  Created by Bryan Higgs on 9/4/24.
//

#include <iostream>

#include "tab.h"

int main(int argc, const char * argv[]) 
{
  std::cout << 'x' << tab << 'y' << tab << 'z' << std::endl;
  
  return 0;
}

and here’s what it outputs:

x	y	z
Program ended with exit code: 0

Stream Manipulators with Arguments

Writing stream manipulators with arguments is a much more advanced topic, beyond the scope of this coverage.

If you want to learn how to do it, you can read Bjarne Stroustrup’s “The C++ Programming Language“, 4th Edition. 

Be warned that it’s not the most readable of books!

Index