【发布时间】:2009-10-08 22:20:14
【问题描述】:
我正在创建一个包含以下部分的记录器:
// #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;
}
}
导致“格式”包含垃圾数据而不是通常的正确字符串。
我认为这是因为
还是我错了?
(为什么 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 函数。
【问题讨论】:
-
“它不起作用”是什么意思?
-
你是对的,你应该复制一个字符串,所以
format应该是std::string类型而不是const std::string &类型。但是,您可以将dynamic_cast放入cout表达式并完全丢失变量。 -
不,我不需要复制。 str() 返回的字符串的内容保证在后续调用这些方法之间保持不变(与 string::c_str() 的方式非常相似)。至于我为什么这样做,我需要格式字符串,因为我实际上想将它传递给采用字符串的单个参数函数,或者传递给采用 char* 的 VARARGS 方法,具体取决于接收到的其他参数。 (但这一切都超出了我的问题的范围 - 得到了满意的回答)
-
澄清一下,我现在的解决方案是
log(stringstream().flush() << "hello " << 1);,但感谢所有其他想法。
标签: c++ iostream stringstream temporary