I have a C++ class where I place many std::cout statements to print informative text messages about a mass of signals that this class is handling. My intentition is to redirect these text messages to a function named log. In this function, I have flag named mVerbose which defines if the log text should be printed. The content of this function is as follows:
 void XXXProxy::log(std::stringstream& ss)
 {
   if(mVerbose)
   {
     std::cout << ss;
     ss << "";
   }
 }
Then, the caller code snippet to this function is as follows: std::stringstream logStr;
 logStr << "SE"
        << getAddr().toString()
        << ": WAITING on epoll..."
        << std::endl;      
 log(logStr);
I would like to overload the << operator in my XXXProxy in a way that I can get rid of creating a std::stringstream object and calling the log function. I want to be able to log the text messages as below and let the << operator aggregate everything into:
 << "SE"
 << getAddr().toString()
 << ": WAITING on epoll..."
 << std::endl;      
So I wouldlike to have an member << function that looks like:
 void XXXProxy::operator << (std::stringstream& ss)
 {
   if(mVerbose)
   {
     std::cout << ss;
     ss << "";
   }
 } 
QUESTION
I am relatively a novice C++ developer and get lots of compilation errors when attemting to write the above stated like << operator. Could you please make some suggestions or direct me to some links for me to correctly implement this << operator. Thanks.
If you don't want to use std::cout directly and you want to have your own Log class, you could implement a simple wrapper providing the same interface of std::ostream: operator<<:
class Log {
private: 
    std::ostream& _out_stream;
    //Constructor: User provides custom output stream, or uses default (std::cout).
    public: Log(std::ostream& stream = std::cout): _out_stream(stream) {} 
    //Implicit conversion to std::ostream
    operator std::ostream() {
        return _out_stream;
    } 
    //Templated operator>> that uses the std::ostream: Everything that has defined 
    //an operator<< for the std::ostream (Everithing "printable" with std::cout 
    //and its colleages) can use this function.    
    template<typename T> 
    Log& operator<< (const T& data) 
    {
        _out_stream << data;
    }
}
So if you implement std::ostream& operator>>(std::ostream& os , const YourClass& object) for your classes, you can use this Log class.
The advantage of this approach is that you use the same mechanism to make std::cout << your_class_object work, and to make the class work with the Log. 
struct Foo
{
    int x = 0; //You marked your question as C++11, so in class initializers 
               //are allowed. 
    //std::ostream::operator<< overload for Foo:
    friend std::ostream& operator<<(std::ostream& os , const Foo& foo)
    {
        os << foo.x;
    }
};
int main()
{
  Log my_log;
  Foo my_foo;
  my_foo.x = 31415;
  my_log << my_foo << std::endl; //This prints "31415" using std::cout.
}
extern const of class Log, and make the class implement a singleton. This allows you to access the Log everywhere in your program.Log output (17:57): log message. To do that, you could use std::endl as a sentinel and store a flag that says when the next output is the beginning of a line (the beginning of a log message). Checkout the next answer for a complete and working implementation.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With