> "C:\MinGW\bin\g++.exe" "C:\CProjects\Forum Help\LoggerExample.cpp" -std=c++0x -Wall -o LoggerExample.exe C:\CProjects\Forum Help\LoggerExample.cpp: In function 'int main()': C:\CProjects\Forum Help\LoggerExample.cpp:81:1: error: no match for 'operator<<' in 'MyLogger((LogLevel)1u) << ": C:\\CProjects\\Forum Help\\LoggerExample.cpp"' C:\CProjects\Forum Help\LoggerExample.cpp:82:1: error: no match for 'operator<<' in 'MyLogger((LogLevel)0u) << ": C:\\CProjects\\Forum Help\\LoggerExample.cpp"' C:\CProjects\Forum Help\LoggerExample.cpp:85:1: error: no match for 'operator<<' in 'MyLogger(((LogLevel)i)) << ": C:\\CProjects\\Forum Help\\LoggerExample.cpp"' C:\CProjects\Forum Help\LoggerExample.cpp:90:1: error: no match for 'operator<<' in 'MyLogger((LogLevel)1u) << ": C:\\CProjects\\Forum Help\\LoggerExample.cpp"' C:\CProjects\Forum Help\LoggerExample.cpp:96:1: error: no match for 'operator<<' in 'MyLogger(logLevel) << ": C:\\CProjects\\Forum Help\\LoggerExample.cpp"'
in Borland the error becomes:
LoggerExample.cpp 81: 'operator<<' not implemented in type 'MyLogger' for arguments of type 'char *' in function main()
So there has to be something wrong with my template operator function:
#include <iostream>
#include <streambuf>
#include <ostream>
#include <fstream>
using namespace std;
/** <Gleened from the internet> - unknown author **/
template <class cT, class traits = std::char_traits<cT> >
class basic_nullbuf: public std::basic_streambuf<cT, traits> {
typename traits::int_type overflow(typename traits::int_type c)
{
return traits::not_eof(c); // indicate success
}
};
template <class cT, class traits = std::char_traits<cT> >
class basic_onullstream: public std::basic_ostream<cT, traits> {
private:
basic_nullbuf<cT, traits> m_sbuf;
public:
basic_onullstream():
std::basic_ios<cT, traits>(&m_sbuf),
std::basic_ostream<cT, traits>(&m_sbuf)
{
init(&m_sbuf);
}
};
typedef basic_onullstream<char> onullstream;
typedef basic_onullstream<wchar_t> wonullstream;
onullstream nout;
/** </Gleened from the internet>**/
enum LogLevel {
LOG_NONE,
LOG_ERROR,
LOG_WARNING,
LOG_INFO,
LOG_NUM_LEVELS
};
const char * LoggingLevels[] = {
"",
"ERROR",
"WARNING",
"INFO",
};
class MyLogger {
static ostream *logout;
public:
static void setLogStream(ostream& os) { logout = &os; }
LogLevel thisLevel;
explicit MyLogger(LogLevel level = LOG_NONE) : thisLevel(level) { }
ostream& logStream() { return (thisLevel == LOG_NONE || logout == NULL) ? nout : *logout; }
};
ostream* MyLogger::logout = NULL;
template<typename T>
ostream& operator<<(MyLogger &mlog, const T& data) {
return (mlog.logStream() << LoggingLevels[mlog.thisLevel] << data);
}
#define LOG(level) (MyLogger(level) << ": " __FILE__ << "(" << __LINE__ << "): ")
int main() {
MyLogger::setLogStream(cout);
LOG(LOG_ERROR) << "I don't know what is going on here" << endl;
LOG(LOG_NONE) << "This should not print" << endl;
for(int i = LOG_NONE; i < LOG_NUM_LEVELS; i++) {
LOG(static_cast<LogLevel>(i)) << "Testing different logging levels(" << i << ")" << endl;;
}
ofstream logfile("TestLog.log");
if (!logfile) {
LOG(LOG_ERROR) << "Could not open log file" << endl;
}
MyLogger::setLogStream(logfile);
LogLevel logLevel = LOG_INFO;
LOG(logLevel) << "This should be redirected to a file" << endl;
logfile.close();
return 0;
}
any ideas?

New Topic/Question
Reply




MultiQuote



|