Reputation: 48141
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;
Upvotes: 2
Views: 174
Reputation: 64308
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;
}
Upvotes: 1