Custom stream to method in C++?

后端 未结 5 524
星月不相逢
星月不相逢 2020-12-06 08:37

I\'m making a logger and I wish to have some kind of stream-like happenings going on, ideally doing CLogger << \"Testing, \" << 1 << \",2,3\\n\";

5条回答
  •  悲哀的现实
    2020-12-06 09:08

    I'm just going to copy-paste my current implementation of this below, it does all you need (and handles things like std::endl and the like). AMBROSIA_DEBUGis macro defined in debug builds, so in theory, every call to this output class should be omitted in release builds (haven't checked though, but seems logical overhead is kept to a minimum. The functionality is based on QDebug functionality, plus a little addition of mine debugLevel, which would allow you to filter debug messages by hand in your code depending on a runtime parameter. Right now it also adds the same amount of spaces before each message.

    // C++ includes
    #include 
    #include 
    
    typedef std::ostream& (*STRFUNC)(std::ostream&);
    
    #ifdef AMBROSIA_DEBUG
        static int debugLevel;
        const static int maxDebugLevel = 9;
    #endif
    
    class Debug
    {
    public:
    
        #ifdef AMBROSIA_DEBUG
        Debug( const int level = 0 )
        : m_output( level <= debugLevel ),
          m_outputSpaces( true ),
          m_spaces( std::string(level, ' ') )
        #else
        Debug( const int )
        #endif // AMBROSIA_DEBUG
        {}
    
        template
        #ifdef AMBROSIA_DEBUG
        Debug& operator<<( const T &output )
        {
            if( m_output )
            {
                if( m_outputSpaces )
                {
                    m_outputSpaces = false;
                    std::cerr << m_spaces;
                }
                std::cerr << output;
            }
        #else
        Debug& operator<<( const T & )
        {
        #endif // AMBROSIA_DEBUG
            return *this;
        }
        // for std::endl and other manipulators
        typedef std::ostream& (*STRFUNC)(std::ostream&);
        #ifdef AMBROSIA_DEBUG
        Debug& operator<<( STRFUNC func )
        {
            if( m_output )
                func(std::cerr);
        #else
        Debug& operator<<( STRFUNC )
        {
        #endif // AMBROSIA_DEBUG
            return *this;
        }
    private:
    #ifdef AMBROSIA_DEBUG
        bool m_output;
        bool m_outputSpaces;
        std::string m_spaces;
    #endif // AMBROSIA_DEBUG
    };
    

    Example usage:

    int main()
    {
        debugLevel = 9; // highest allowed in my app...
        Debug(4) << "This message should have an indentation of 4 spaces." << endl;
        Debug(8) << "This is a level 8 debug message.\n";
        return 0;
    }
    

提交回复
热议问题