stdplus::stringfmt

A library for generating formatted strings
Copyright (c) 2003 Early Ehlinger
Index

Download

stdplus_stringfmt.zip

License

Gnu Lesser General Public License, v2.1 (Included in the Code)

Authors

  • Early Ehlinger early@ehlinger.com
  • Installation

    Somewhere on your include path, unzip stdplus_stringfmt.zip. A file should be placed into a folder called stdplus:

  • stringfmt.h
  • Overview

    I have been quite frustrated by having to create a (named) temporary object of type std::stringstream just to format strings before calling a function:

    
    std::stringstream temp;
    temp << [a bunch of stuff];
    some_function_that_takes_a_string( temp.str() );
    

    I find that this idiom makes code quite difficult to read. One approach around it would be to overload some_function_that_takes_a_string to also take a std::stringstream and call it like so:

    
    std::stringstream temp;
    temp << [a bunch of stuff];
    some_function_that_takes_a_string( temp );
    

    This is still weak, because you have to declare temp!

    So I started toying around with the idea of using an unnamed std::stringstream, like so

    
    some_function_that_takes_a_string
      ( std::stringstream() << [a bunch of stuff] );
    

    The problem here is that operator<< returns a std::ostream. Clearly you don't want to overload some_function_that_takes_a_string to accept a std::ostream, since other stream types wouldn't make any sense with this function. So I wrote an object called string_extractor that dynamic_cast'd the ostream back to a std::stringstream and returned its string, yielding:

    
    some_function_that_takes_a_string
      ( std::stringstream() << [a bunch of stuff] 
        << stdplus::string_extractor );
    

    This seemed to work fine until I actually ran it. For some reason, the stream kept getting garbled up. Although I never figured out why, it forced me to rethink my approach. What I really needed was something compatible with std::string that also supported all of the operators << that std::ostream supports. Enter template magic!

    If you look at the implementation of stringfmt, you'll notice that it has a templatized operator<< that takes any OTHER type and tries to use operator<< to in turn insert the other value into m_stream. It then returns a reference to itself. Because it returns a reference to stringfmt as opposed to a reference to std::ostream, when it comes time to pass the stringfmt to another function that takes a std::string, the implicit conversion via operator std::string() is considered and (hurrah!) used.

    The end result is that now you can do this:

    
    some_function_that_takes_a_string
      ( stdplus::stringfmt() << [a bunch of stuff] );
    

    I've started integrating stringfmt around my codebase, taking out a slew of explicit references to std::stringstream and I can say that, at least in my case, it has really improved the readability of my code. In fact, I have written a similar class, AnsiStringfmt, that I am now using for functions that take Borland C++ Builder's AnsiString class.

    Usage

    Simply include <stdplus/stringfmt.h> in your project and enjoy.

    
    #include <stdplus/stringfmt.h>
    
    std::string test =
      stdplus::stringfmt( )
      << "Hello There.  This is kind of a pointless example, but hey, it\'s just an example!";
    
    // Or Better:
    some_function_that_takes_a_string
      ( stdplus::stringfmt( )
        << "Hello there.  This is a string generated inline with numbers, too:" << 32
      );
    

    Notes

    Currently none.