1

I'm using threads and need to protect the std::cout operations with a mutex, but i don't know how to overload the operator << to use it in sequence like this:

myOut << "hello " << 55 << " world" << false << 45.4f << std::endl;

If someone can help me i'll thank you.

user2542813
  • 323
  • 3
  • 12
  • 1
    http://stackoverflow.com/questions/4421706/operator-overloading – Deduplicator Jun 13 '14 at 15:38
  • Something like this should be done at the level of the stream buffer. [Here's an implementation of a thread safe buffer by Dietmar.](http://stackoverflow.com/a/12413298/701092) – David G Jun 13 '14 at 15:41
  • @0x499602D2: Actually, that's much too low-level. Better would be an object wrapping a `std::stringstream` and either a reference to a thread-safe stream-object, or a stream-object and a mutex. Only write to the underlying object once, on destruction of the wrapper. So, far less synchronization overhead, and the message will not be interleaved with others. – Deduplicator Jun 13 '14 at 15:49
  • 1
    A question wanting the same, just for logging: http://stackoverflow.com/questions/9297099/c-ostream-operator-as-argument – Deduplicator Jun 13 '14 at 15:55

1 Answers1

1

thanks you all folks, but i solved the question, is easy but repetitious, i need to make the operator<< to return an MyClass&, then i use this returned value to call the operator<< as many times as i want, like this:

    Log& operator<<(const std::string& p){
    std::lock_guard<std::mutex> locker(mutex);
    std::cout << p;
            return *this;
}

    Log& operator<<(const std::string& p){
    std::lock_guard<std::mutex> locker(mutex);
    std::cout << p.c_str();
            return *this;
}

But need to overload for any type that you want to use and them just create a global variable for it

user2542813
  • 323
  • 3
  • 12
  • it's a good idea, i will add it into my personal framework :) – user2542813 Jun 13 '14 at 16:33
  • Did you follow my link [here?](http://stackoverflow.com/questions/9297099/c-ostream-operator-as-argument) That approach avoids any overloading of `operator<<`, reducing your custom code to the absolute minimum. Much better imo. – Deduplicator Jun 13 '14 at 16:36
  • i read now, the '#define log' is great t.t, and must be more fast, but what if the std::cout throws an exception? in this case the std::lock_guard can't be used to unlock the mutex, so we need i try-catch to release the mutex an re-trow the exception. – user2542813 Jun 13 '14 at 17:10
  • @user2542813: I actually prefer the accepted answer by Ben Voigt. No need to involve the preprocessor. – Deduplicator Jun 13 '14 at 17:22
  • hey, if the current operator<< return, we will come back to the caller function(mutex is now unlocked), and if at this moment the scheduler stop the current thread and change to the other that use the shared class? i think this is possible, am i right? if this is possible the way that a mentioned above is not safe. – user2542813 Jun 13 '14 at 17:49
  • How the Ben Voigt way could avoid the overloads? it must return a class that offers mutex protection, in this case an class created by the programmer, and different of the '#define log' we can't pass a undefined type because it's not a text substitution. – user2542813 Jun 13 '14 at 17:49
  • To solve the first problem, i think i can use a global mutex for the class, and unlock it on the destructor,but need to be a recursive mutex because it will be called in every call of the operator<<, we need also a counter to unlock as many times as we locked it – user2542813 Jun 13 '14 at 17:50