My Favorite C++ Macro
It is widely understood that C/C++ preprocessor macros are dangerous and should be avoided, especially when they can easily be replaced by a constant or template. However, there’s one macro I came up with that I really like:
#define MAKE_STRING(v) (static_cast<std::ostringstream&>(std::ostringstream().flush() << v)).str()
And here’s an example usage:
float x = 3.14f;
std::string x = MAKE_STRING("The value of x is " << x);
This macro dispenses with all the annoying boilerplate of setting up an ostringstream, writing to it, and storing the result in a string. It takes advantage of the fact that the stream insertion operator (<<) returns the stream that was passed to it, so we can chain together a bunch of insertions, cast the result back to an ostringstream and get the resulting string. Undoubtedly, there are more “elegant” ways to do this with templates. Here’s why I like this macro:
- It’s simple
- It’s one line so I can throw it into a project without pulling in all of boost
- The usage is very intuitive
It also makes a nice base for, say a log4cxx wrapper:
#define LOG_INFO(v) getLogger()->info(MAKE_STRING(v))
Now logging mixed types is a snap, and you can turn off all logging with a simple preprocessor conditional.
Caveats? Of course there are…
- Still suffers from multiple evaluation problems typical of all macros with value arguments
- Probably not all that fast
Neither of these has bitten me yet in several years of use. Be careful though, it’s viral. Once I showed it to my coworkers it started springing up everywhere for better and worse :)