Временная проблема возврата Ostream
Я создаю регистратор со следующими разделами:
// #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__)
которая сопоставляет varrgs printf-подобные функции журнала, принимающие char *, string () и ostream (), а также функции не vararg, принимающие string (), exception () и HRESULT.