我正在尝试将自己的代码从VS2012移植到g ++ 4.8。
我收到了这个恭维错误:
AllocationManager.cpp: In member function ‘void AllocationManager::printMemoryLeaks()’:
TRLogger.h:247:42: error: ‘streamAggrator’ was not declared in this scope
#define TRLOG_INFO streamAggrator(logINFO) << PACKET_DESCRIPTION << __FUNCTION__ << ":" << __LINE__ << ": "
^
AllocationManager.cpp:39:2: note: in expansion of macro ‘TRLOG_INFO’
TRLOG_INFO << "sdfs\n";
其中printMemoryLeaks
是虚函数(AllocationManager
未模板化):
void AllocationManager::printMemoryLeaks(void)
{
TRLOG_INFO << "sdfs\n";
}
在文件TRLogger.h
中:
enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
class streamAggrator
{
public:
streamAggrator(TLogLevel logLevel);
/* private: */
FILELog fLog;
WarnLog wlog;
std::ostringstream& s1;
std::ostringstream& s2;
};
template<typename T>
streamAggrator& operator<<(streamAggrator& agg, const T& obj)
{
agg.s1 << obj;
agg.s2 << obj;
agg.s2.flush();
return agg;
}
...
#define TRLOG_INFO streamAggrator(logINFO) << PACKET_DESCRIPTION << __FUNCTION__ << ":" << __LINE__ << ": "
如何解决此问题 - 我找不到任何可以使用this
或using
来帮助编译器的地方。
谢谢, 盖
答案 0 :(得分:4)
您当前的问题是,您尝试将临时streamAggrator
对象传递给一个函数,该函数需要streamAggrator
非const
引用。您不能将临时对象绑定到非const
引用。解决此问题的方法是使streamAggrator
的输出运算符成员:虽然您无法将临时绑定到非const
引用,但可以调用非 - const
成员函数。请注意,你也会遇到像std::flush
这样的操纵者的问题(问题是这些是模板本身,你实际上需要一个具体的操作符来调用它们让编译器推断出他们的模板参数)。
显然,我会正确地解决问题,即,不是试图挖掘不创建流的解决方案的尝试,而是创建std::streambuf
做实际的工作。您的示例没有做任何有用的事情,即,我无法确切地告诉您要做什么,但代码看起来非常像尝试执行teestream
之类的操作:写一次但将输出发送到多个destintations。我在帖子中发布了相应的流缓冲区(主要是在Usenet上,但我认为,至少在Stackoverflow上也是如此)。
虽然我不知道如何摆脱宏来填充__FILE__
和__LINE__
,但实际的流格式化可能应该使用流缓冲区:
struct teebuf: std::streambuf {
private:
std::streambuf* sb1;
std::streambuf* sb2;
public:
teebuf(std::streambuf* sb1, std::streambuf* sb2): sb1(sb1), sb2(sb2) {}
int overflow(int c) {
this->sb1->sputc(c);
this->sb2->sputc(c);
return std::char_traits<char>::not_eof(c);
}
int sync() {
this->sb1->pubsync();
this->sb2->pubsync();
}
};
class logstream
: std::ostream {
std::ofstream out;
teebuf sbuf;
public:
logstream()
: out("file.log")
, sbuf(out.rdbuf(), std::clog.rdbuf()) {
this->init(&this->sbuf);
}
logstream(logstream&& other)
: out(std::move(other.out))
, sbuf(std::move(other.sbuf)) {
this->init(&this->sbuf);
};
我认为您可以返回日志流。我不知道你的日志记录级别是什么意思,但我想在准备问题时它的处理被删除了:可能需要更改实现以适当考虑日志记录级别。