Click here to Skip to main content
Licence 
First Posted 8 Jan 2005
Views 35,027
Bookmarked 21 times

Piping between Functions

By | 8 Jan 2005 | Article
A trivial way to pipe the cout from one function to the cin of another.

Introduction

This article describes how we can pipe functions together as we would program on the command line.

Filters

A filter is a program which takes its input from the standard input stream (std::cin) and places its output to the standard output stream (std::cout). The reason for writing a program as a filter is that it can be used from the OS shell, to redirect its output to a file or device. Filters can also be piped together, which means redirecting the output from one program to the input of the other. This makes programs written as filters highly flexible and hence more reusable.

Functions as Filters

A function often behaves like a filter, taking some input from the standard input and outputting to the standard output. So there is no reason why we can't treat a function like we would treat a filter, and redirect its standard output to the standard input of another.

Example

Let's say we have the following functions, which operate on the cin and cout streams:

void HelloWorld() { 
  cout << "hello world" << endl;  
}

void CountChars() {
  string s;
  getline(cin, s);
  cout << static_cast<int>(s.size()) << endl;
}

By overloading the greater-than operator (>), we can now write a new function, which outputs the number of characters output onto the stream by HelloWorld().

void CountCharsInHelloWorld() {
  filter(HelloWorld) > filter(CountChars);
}

The Code

The code to accomplish this functionality is quite simple.

#include <iostream>
#include <sstream>

using namespace std;

typedef void(*procedure)();

class filter {
  public:
    filter(procedure x) : proc(x) { }
    void operator()(istream& in, ostream& out) {
      streambuf* inbuf = cin.rdbuf();
      streambuf* outbuf = cout.rdbuf();
      cin.rdbuf(in.rdbuf());
      cout.rdbuf(out.rdbuf());
      proc();
      cin.rdbuf(inbuf);
      cout.rdbuf(outbuf);
    }
  private:
    procedure proc;
};

void operator>(filter f1, filter f2) {
  stringstream s;
  f1(cin, s);
  s.seekg(0);
  f2(s, cout);
}

Summary

This is a very simple technique, but it can be used to write our code in a manner which is much easier to reuse. All of those UNIX programmers weren't wrong!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Christopher Diggins

Architect
Autodesk
Canada Canada

Member

Follow on Twitter Follow on Twitter
I've been programming personal computers since my I got my first Atari 400 in 1980. I currently work at Autodesk as an SDK specialist.
 
One of my passions is the design and implementation of programming languages. My current project is the Jigsaw library which includes a parsing engine and other utilities for implementing programming languages in C#.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalpiping two functions/programs Pinmemberav283616:46 25 Apr '07  
GeneralC++ VS 2003 PinmemberLorad3:48 10 Jan '05  
GeneralRe: C++ VS 2003 Pinmembercdiggins4:31 10 Jan '05  
GeneralNice Hack! PinmemberMr.Prakash16:53 8 Jan '05  
GeneralRe: Nice Hack! Pinmembercdiggins17:05 8 Jan '05  
Thanks for the compliment. I would argue that it doesn't really change the meaning of the operator, because an operator only has meaning with regards to its context, i.e. the types of the parameters passed to it. It is also worthwhile to point out that streams overload >> and << which have separate meanings for ints.
 
Christopher Diggins
<a href="http://www.cdiggins.com">www.CDiggins.com</a>
<a href="http://www.heron-language.com">www.Heron-Language.com</a>

GeneralRe: Nice Hack! PinmemberDon Clugston14:19 9 Jan '05  
GeneralRe: Nice Hack! Pinmembercdiggins17:06 9 Jan '05  
GeneralRe: Nice Hack! PinmemberDon Clugston18:08 9 Jan '05  
GeneralRe: Nice Hack! Pinmembercdiggins4:36 10 Jan '05  
GeneralRe: Nice Hack! Pinmembercdiggins3:40 12 Jan '05  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120528.1 | Last Updated 8 Jan 2005
Article Copyright 2005 by Christopher Diggins
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid