iostream maniputor via xalloc/iword or via derived class?

1k Views Asked by At

I need to implement a C++ iostream manipulator. Reading here and there it seems that people uses 2 ways

  1. using ios_base::xalloc and ios_base::iword

  2. implementing a derived class from iostream like example below.

I like the second way but probably it has cons that I cannot see or understand compared to the first way.

    // Example of point 2
    struct mystream : public iostream
    {  
      ostream& o_;
      mystream(ostream& o) : o_(o) {} 

      ostream& operator << (int a) {
        // do something with o and a
        o << "<A>" << a << "</A>";
        return *this;
      }     
     };

     ostream mymanipulator(ostream& out) { 
       return mystream(out);
     }

I found a very good implementation of way #2 in this post Custom manipulator for C++ iostream.

It looks to me that xalloc and iword are more used to store some custom internal state for my custom stream to be used at some point.

1

There are 1 best solutions below

4
On BEST ANSWER

I wouldn't recommend either of those things.

Using ios_base::xalloc and ios_base::iword

You haven't exactly told us how you would use the data stored in the stream, but it's a bit unintuitive to set iword() each and every time you want to write.

Implementing a derived class from iostream...

Normally you don't want to inherit from the stream base classes. The only case in which it might be useful is when you're wrapping a custom stream around a stream buffer, but that's usually for convenience.

Another problem is that your inserter returns std::ostream, meaning that when chaining operators you'll only be writing to the std::ostream base object on the second write:

mystream str;
str << 100  // writes "<A>100</A>"
    << 200; // only writes 200

The idiomatic solution is to customize a std::num_put<char> facet for your stream's locale. This way you wrap the functionality directly under the hood of the stream so that it doesn't change the way the user uses the stream.