Я создаю регистратор со следующими разделами:
// #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, если это возможно)
Просто чтобы дать представление, пример одного из моих реальных #define:
#define LOG_DEBUG_MSG(format, ...) \
LogMessage(DEBUG_TYPE, const char* filepos, sizeof( __QUOTE__( @__VA_ARGS__ )), \
format, __VA_ARGS__)
который соответствует varargs функциям журнала, подобным printf, принимающим char*, string() и ostream(), а также функциям без vararg, принимающим string(), exception() и HRESULT.
format
должен быть типаstd::string
, а не типаconst std::string &
. Однако вы можете просто поместитьdynamic_cast
в выражениеcout
и полностью потерять переменную. - person KayEss   schedule 09.10.2009log(stringstream().flush() << "hello " << 1);
, но спасибо за все остальные идеи. - person Marius   schedule 10.10.2009