I’ve been working on a custom Logging system for Vortex. After thinking about it for a while, I decided to go with a stream-based API for logging. I figured this would allow me to both: provide output capabilities for custom data types and also to format log messages “on the fly”.
This is where I started to play with the idea of being able to handle std::endl just like the standard streams.
Even though I’ve been a C++ programmer for a while (10 years since my first “hello world” program), I realized I actually didn’t know the type of std::endl. I looked around until I finally found something at Stack Overflow. Much to my surprise, it turns out std::endl is a function template! The correct way to handle it is, in the stream insertion operator (<<), call the passed-in endl function with the stream you are outputting to as the parameter.
// The code in Vortex is more involved,
// but this is the general idea
Logger& Logger::operator<<(std::ostream& (*f)(std::ostream&))
For Vortex, it was enough just to support std::endl taking and receiving std::ostream instances, it might be different in your code, depending on the degree of customization you want to provide.
Now that everything’s in place, we can handle std::endl just like any other stream:
debug << "running loggerTest() in file.cpp:12" << std::endl;