我正在创建一个包含以下部分的记录器:
// #define LOG(x) // for release mode
#define LOG(x) log(x)
log(const string& str);
log(const ostream& str);
带着这样的想法:
LOG("Test");
LOG(string("Testing") + " 123");
stringstream s;
LOG(s << "Testing" << 1 << "two" << 3);
这一切都按预期工作,但是当我这样做时:
LOG(stringstream() << "Testing" << 1 << "two" << 3);
这没用:
void log(const ostream& os)
{
std::streambuf* buf = os.rdbuf();
if( buf && typeid(*buf) == typeid(std::stringbuf) )
{
const std::string& format = dynamic_cast<std::stringbuf&>(*buf).str();
cout << format << endl;
}
}
导致“格式”包含垃圾数据而不是通常的正确字符串。
我认为这是因为 << 运算符返回的临时 ostream 超过了它来自的字符串流。
还是我错了?
(为什么 string() 以这种方式工作?是因为它返回对自身的引用吗?我假设是的。)
我真的很想这样做,因为我会在登录发布模式时消除额外的分配。
任何以这种方式完成它的指针或技巧都将受到欢迎。在我的实际解决方案中,我有许多不同的日志功能,它们都比这更复杂。所以我希望在调用代码中以某种方式实现它。(如果可能,不要修改我的#define)
只是给出一个想法,我的一个实际#defines的一个例子:
#define LOG_DEBUG_MSG(format, ...) \
LogMessage(DEBUG_TYPE, const char* filepos, sizeof( __QUOTE__( @__VA_ARGS__ )), \
format, __VA_ARGS__)
它匹配采用 char*、string() 和 ostream() 的 varargs printf-like log 函数以及采用 string()、exception() 和 HRESULT 的非 vararg 函数。