Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

Creating manipulators

Sometimes you d like to create your own manipulators, and it turns out to be remarkably simple. A zero-argument manipulator such as endl is simply a function that takes as its argument an ostream reference and returns an ostream reference. The declaration for endl is

ostream& endl(ostream&);
 

Now, when you say:

cout << "howdy" << endl;
 

the endl produces the address of that function. So the compiler asks, Is there a function that can be applied here that takes the address of a function as its argument? Predefined functions in <iostream> do this; they re called applicators (because they apply a function to a stream). The applicator calls its function argument, passing it the ostream object as its argument. You don t need to know how applicators work to create your own manipulator; you only need to know that they exist. Here s the (simplified) code for an ostream applicator:

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

The actual definition is a little more complicated since it involves templates, but this code illustrates the technique. When a function such as *pf (that takes a stream parameter and returns a stream reference) is inserted into a stream, this applicator function is called, which in turn executes the function to which pf points. Applicators for ios_base, basic_ios, basic_ostream, and basic_istream are predefined in the Standard C++ library.

To illustrate the process, here s a trivial example that creates a manipulator called nl that is equivalent to just inserting a newline into a stream (i.e., no flushing of the stream occurs, as with endl):

//: C04:nl.cpp
// Creating a manipulator.
#include <iostream>
using namespace std;
 
ostream& nl(ostream& os) {
return os << '\n';
}
 
int main() {
cout << "newlines" << nl << "between" << nl
<< "each" << nl << "word" << nl;
} ///:~
 

When you insert nl into an output stream, such as cout, the following sequence of calls ensues:

cout.operator<<(nl) nl(cout)
 

The expression

os << '\n';
 

inside nl( ) calls ostream::operator(char), which returns the stream, which is what is ultimately returned from nl( ).[47]

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire