我一直在阅读大量的问题,文章和文档,但我找不到解决问题的方法。
我想创建一个用于调试的简单类。最终的结果将允许我做这样的事情:
logger << error << L"This is a problem!" << endl;
logger << warning << L"This might be a problem!" << endl;
logger << info << L"This isn't a problem but I thought you should know about it" << endl;
有了这个想法,我可以在记录器类中切换这些东西是否能成为控制台/调试文件。
logger.setLevel(ERROR);
我有一个骨架,但我不能让操作员重载以使操纵器工作。
这是Logger.h:
class LoggerBuffer : public wfilebuf {
// Functions
public:
LoggerBuffer() { wfilebuf::open("NUL", ios::out); currentState = 1;}
~LoggerBuffer() {wcout << "DELETED!" << endl;}
void open(const char fname[]);
void close() {wfilebuf::close();}
virtual int sync();
void setState(int newState);
// Variables
private:
int currentState;
};
class LoggerStream : public wostream {
// Functions
public:
LoggerStream() : wostream(new LoggerBuffer()), wios(0) {}
~LoggerStream() { delete rdbuf(); }
void open(const char fname[] = 0) {
wcout << "Stream Opening " << fname << endl;((LoggerBuffer*)rdbuf())->open(fname); }
void close() { ((LoggerBuffer*)rdbuf())->close(); }
void setState(int newState);
};
和Logger.cpp:
void LoggerBuffer::open(const char fname[]) {
wcout << "Buffer Opening " << fname << endl;
close();
wfilebuf* temp = wfilebuf::open(fname, ios::out);
wcout << "Temp: " << temp << endl;
}
int LoggerBuffer::sync() {
wcout << "Current State: " << currentState << ", Data: " << pbase();
return wfilebuf::sync();
}
void LoggerBuffer::setState(int newState) {
wcout << "New buffer state = " << newState << endl;
currentState = newState;
}
void LoggerStream::setState(int newState) {
wcout << "New stream state = " << newState << endl;
((LoggerBuffer*)rdbuf())->setState(newState);
}
和main.cpp:
struct doSetState {
int _l;
doSetState ( int l ): _l ( l ) {}
friend LoggerStream& operator<< (LoggerStream& os, doSetState fb ) {
os.setState(3);
return (os);
}
};
...
LoggerStream test;
test.open("debug.txt");
test << "Setting state!" << doSetState(1) << endl;
...
此混乱在VS2005中产生以下错误:
“错误C2679:二进制'&lt;&lt;' :不 运营商发现哪个需要 类型的右手操作数 'doSetState'(或者没有 可接受的转换)“
非常感谢任何帮助。
谢谢!
答案 0 :(得分:0)
您的ostream运算符没有正确的签名。它应该是:
friend LoggerStream& operator<< (LoggerStream& os, const doSetState& fb )
(有必要使用引用,因为单通道编译器在类定义的中途时不知道doSetState的大小。)
答案 1 :(得分:0)
问题是当你这样做时:
test << "Setting state!"
它返回一个基本的wostream对象。所以链接它不起作用,因为没有过载:
wostream& operator<< (wostream& os, const doSetState& fb )
然而,您可以在不同的行上执行此操作,如下所示:
test << "Setting state!";
test << doSetState(1) << endl;
答案 2 :(得分:0)
我会采用稍微不同的方法。
我没有从std::wostream
继承,而是在我的记录器类中拥有std::wfostream
成员。然后,您可以使用通用模板化operator<<
来有选择地转发到嵌入流。
例如:
class Logger;
template<class T> Logger& operator<<(Logger&, const T&);
enum LogLevel
{
debug,
info,
warning,
error
};
class Logger
{
public:
void open(const char* file) { stream.open(file); }
void close() { stream.close(); }
void passLevel(Loglevel level) { pass = level; }
void logLevel(LogLevel level) { current = level; }
private:
bool passThrough() { return current >= pass; }
std::wofstream stream;
LogLevel pass;
LogLevel current;
friend template<class T> Logger& operator<<(Logger&, const T&);
};
template<class T>
Logger& operator<<(Logger& log, const T& rhs)
{
if (log.passthrough())
{
log.stream << rhs;
}
return log;
}
Logger& operator<<(Logger&, LogLevel level)
{
log.logLevel(level);
return log;
}
struct setLogLevel {
setLogLevel(LogLevel l) : level(l) { }
LogLevel level;
};
Logger& operator<<(Logger&, const setLogLevel setter)
{
log.passLevel(setter.level);
return log;
}