简体   繁体   中英

Stream manipulator with a simple Logger

So I have this simple C++ Logger class.

class Log{
public:
    Log(const int& msgLevel = 1){
        this->msgLevel = msgLevel;
    }

    template <class T>
    Log& operator<<(const T& v){
        if (msgLevel<=level) {
            std::cout << v;
        }
        return *this;
    }

    ~Log(){

    }

    static int level;
    int msgLevel;
};

int Log::level = 1;

I can use it like this:

Log(1)<<"My debug info: "<<otherVariable;

The problem is when I try to use endl :

Log(1)<<"My debug info: "<<otherVariable<<endl;

I get this error:

error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'Log' (or there is no acceptable conversion)

To solve this error I need to add another method to my class like this:

// For manipulators like endl
Log& operator<< (ostream& (*pf) (ostream&)) {
    if (msgLevel<=level) {
        cout << pf;
    }

    return *this;
}

But adding this method just to handle endl it seems a bit an overkill to me. Are there any better alternative?

Another alternative would be just to use "\\n" instead of endl;

Because endl is a function template, the simple version of operator<< isn't good enough, because there are multiple possible ways it could match by using different template arguments for endl . Adding the second overload is probably the best you can do.

You could, however, factor out the common logic, like this:

template <class T>
Log& operator<<(const T& v){ return write(v); }

Log& operator<<(ostream& (*v)(ostream&)){ return write(v); }


template <typename T>
Log& write(const T &v)
{
    if (msgLevel<=level) {
        std::cout << v;
    }
    return *this;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM