Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
404 views
in Technique[技术] by (71.8m points)

c++ - conditional debug output class with templated operator<<

I'm trying to create a simple qDebug-like class I can use to output debug messages in debug mode, dependant on some debug level passed when calling the app. I liked the ease of use of the QDebug class (which could be used as a std::cerr and would disappear when compiling in release mode). I have this so far:

#ifdef DEBUG
    static int CAKE_DebugLevel;

    class Debug
    {
        Debug( int level ) : m_output( level <= CAKE_DebugLevel ) {}

        template<typename T>
        Debug& operator<<( T )
        {
            if( m_output )
            {
                std::cout << T;
                return *this;
            }
            else
                return *this;
        }
    private:
        bool m_output;
    };
#else // release mode compile
    #define Debug nullstream
#endif // DEBUG

I think a nullstream-kind of thing would be best for the release mode define:

class nullstream{};

template <typename T>
nullstream& operator<<(nullstream& ns, T)
{
    return ns;
}

In main I have for the moment:

#include "Debug.h"

#include <iostream>

int main()
{
    Debug(0) << "Running debug version of CAKE." << std::endl;
}

Which is giving the following error with gcc 4.5.1:

In member function 'Debug& CAKE_Debug::operator<<(T)': expected primary-expression before ';' token (points at the line std::cout << T;)

In function 'int main(int, char**, char**)': expected unqualified-id before '<<' token

I'm sure it's something simple, but all the general template info I've found turns up nothing. Thanks for any help!

If you need more info, please ask.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your nullstream class has no integral constructor. This means that when you #define Debug nullstream, the compiler can't recognize Debug(0) - that makes no sense. Debug is not a macro that takes arguments, and if you substitute with nullstream, nullstream has no constructor that takes arguments. #define used this way is oh so wrong. You should have something like this:

#ifdef _DEBUG
static int CAKE_Debuglevel;
#endif

class Debug
{
    Debug( int level ) 
#ifdef _DEBUG
    : m_output( level <= CAKE_DebugLevel ) 
#endif
        {}

    template<typename T>
    Debug& operator<<( T t)
    {
        #ifdef _DEBUG
        if( m_output )
        {
            std::cout << t;
            return *this;
        }
        else
        #endif
            return *this;
    }
private:
#ifdef _DEBUG
    bool m_output;
#endif
};

Now your class really will look and act the same in any environment but only output if _DEBUG is defined. I also fixed the bug where you tried to output a type.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...