Manipulating an output stream

Feb 10, 2009 at 10:32pm
Hello everyone,

I have a class called entry. For this class I have defined the operator<< to be able to write
1
2
entry item;
std::cout << item;

output: entry name: item

Now, I want to define another operator<< to manipulate this stream, e.g. leave out every second char (see the line output). Therefor, I have to define a struct, say filter, I think:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct filter {
  filter() {};

  std::ostream& operator<<( std::ostream &os /*not sure here*/ ) {
    //code for filtering here
    //simplest case, do nothing to the stream, just tell:
    os << "Yes, we can!";
    return os;
  }
};

filter f;
entry item;
std::cout << f << item;

output: ety ae: ie

The signature of the operator<< for the class entry is
friend std::ostream& operator<<( std::ostream &os, const entry &obj );
But I am not able to get this right for the filter. The entry operator takes a reference to the stream (&os) and another one to the object it operates on (&obj). But the operator filter should take a stream object as its right hand argument as well, right?

May someone please point me to a solution or documentation?

Another question: Is this sensible design? I want to be able to reuse the functionality in the filter class. Therefor I do not want to implement this in the operator<< of the entry class. But I have read that streams are horribly slow, and that some people use fprintf instead. Is this the better way? ( At the moment I do not even know if fprintf works with custom data types.)

I thank you in advance!
Best, Wolfgang.
Feb 11, 2009 at 10:46am
I believe you're thinking of manipulators. The standard ones are declared in iomanip.

I think you want to change what appears on the stream. This sounds more like a customisation object that takes your entry class as a paramater and knows how to output parts of it to the stream. Your code would look more like
1
2
3
    entry item;
    filter f(item);
    std::cout << f;


I hope that helps.
Feb 11, 2009 at 11:04am
1
2
3
4
 
entry item;
filter f(item);
std::cout << f


Yes, this would of course be possible, but to me the line std::cout << f << item; looks more elegant, because it models what is done: There is a stream, and the data in the stream. should me manipulated. Imagine, there is not only one manipulation but n, then you can just use std::cout << f1 << f2 << ... << fn << item;. Otherwise you have to nest it like f1(f2(...fn(ifem)...));.

But I think the manipulators you mentioned are the right place for me to dig.
Thank you very much!
Topic archived. No new replies allowed.