Boost logo

Boost :

From: Cédric Venet (cedric.venet_at_[hidden])
Date: 2007-06-18 13:10:20


> bounces_at_[hidden]] De la part de Ion Gaztañaga
>
> -> Hard formatting: printf/scanf are much easier to use and they don't
> need several hundred of function calls to do their job. The operator<<
> overloading is also a problem if each call needs some internal locking.
> A formatting syntax that can minimize the locking needs would be a good
> choice. I would be really happy with a type-safe printf (variadic
> templates to the rescue).
>

You can limit the need of locking call pretty easily, even with operator <<.
You just need to use a temporary object which unlock the mutex when
destroyed:

Class stream;

Class OStreamObj {
Public:
        Explicit OStreamObj(stream& s): m_stream (s) { m_stream.lock(); }
        OStreamObj(const OStreamObj& o); // somethings smart
        ~OStreamObj() { m_stream.unlock(); }
Private:
        stream& m_stream;
};
Class stream {
Public:
        Void Lock();
        Void Unlock();
Private:
        Mutex m_mutex;
};
Template< class T >
Inline OStreamObj Operator<<(stream& s, const T& t) {
        OStreamObj oso(s);
        Oso << t;
        Return Oso;
}
// all the overload of << are on OStreamObj
Inline OStreamObj& Operator<<( OStreamObj& oso, int i) {
        Oso.put_int(i);
        Return Oso;
}

Somethings like this (probably with a counter one the mutex or other c++
tricks to avoid the lock unlock of the first copy).

I use the same kind of tricks for automatically putting a std::endl at the
end of my logging primitive.

        struct AutoEndLine {
                AutoEndLine(std::ostream& os):m_ostream(os) {}
                ~AutoEndLine() { m_ostream << std::endl; }

                template< class T > AutoEndLine& operator<< (const T& e) {
m_ostream<<e; return *this; }

                operator std::ostream&() { return m_ostream; }
        private:
                std::ostream& m_ostream;
        };

#define LOG if(IS_LOG_ACTIVATE) ::CT::AutoEndLine(::std::cout)<< "LOG: "

There is some advantage to operator << or %, for example, I like to do:
LOG << "foo " << foo;
ASSERT(f!=NULL) << "Error";
DEBUG << "bar";

With #define DEBUG if(debug_active) LOG << "Debug: "
Or somethings like this.

Anyways, I don't think this is a good argument against <<. Even if I agree
with you on all the point of your previous post.

-- 
Cédric Venet

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk