2015-05-09

Automatically flushing QTextStream

QTextStream is way more convenient for printing to console than C++ streams are. Therefore, I usually replace cerr and cout by qerr and qout in projects using Qt:

Header file:
     extern QTextStream qerr;
     extern QTextStream qout;

Source file:
     QTextStream qerr(stderr, QIODevice::WriteOnly | QIODevice::Text);
     QTextStream qout(stdout, QIODevice::WriteOnly | QIODevice::Text);

Unfortunately, QTextStream buffers and is not able to automatically flush. This means it may print a message later than expected or not at all if the program crashes. This is obviously undesirable for a cerr replacement.

One way to work around this is by intercepting all stream operator calls and adding a call to flush():

Header file:
    class AutoFlushingQTextStream : public QTextStream {
    public:
        AutoFlushingQTextStream(FILE* f, QIODevice::OpenMode o)
                : QTextStream(f, o) {} 

        template<typename T>
        AutoFlushingQTextStream& operator<<(T&& s) {
            *((QTextStream*) this) << std::forward<T>(s);
            flush(); 
            return *this; 
        }
    };

    extern AutoFlushingQTextStream qerr;
    extern QTextStream qout;

Source file:
    AutoFlushingQTextStream qerr(stderr, QIODevice::WriteOnly | QIODevice::Text);
    QTextStream qout(stdout, QIODevice::WriteOnly | QIODevice::Text);


Any Tips for improving the code are very much appreciated.

No comments:

Post a Comment