As Peter87 has already said, operator() is defined for LoggerStream references, not pointers, so you need to dereference the pointer before using operator()
You could, of course, use a macro to keep the usage tidy, such as
LoggerStream* plog_ = LoggerStream::instance();
#define LOG(LEVEL) if(0 != plog_) (*plog_)(LEVEL)
But once you're using a macro, you might as well use a normal function rather than operator(), and could even pass the file name and line number to it.
Where LogStream has a method
LogStream& getStream(LogLevel level, const char* filePath, int lineNum);
the macro could become
#define LOG(LEVEL) if(0 != plog_) plog_->getStream(LEVEL, __FILE__, __LINE__)
|I see in your example, you have a reference to self in all of your operator overloads as your first parameter and you do not have a definition for each operator in your class header as public.|
Is this needed?
No, it's just a stylistic thing. Coding them as member functions is equally valid.
But I do usually code my insertion operators that way (as non-member functions) if I have a suitable method for the insertion operator to call to do the real work as it makes the class body less cluttered.
|I like the endl addition you did in your example.|
Actually, it shouldn't be needed. If you derive your LoggerStream from std::ostream then you will get the handling of all the built-in types, std::string, and io manipulators as part of the deal.