Създавам логер със следните секции:
// #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__)
което съответства на varargs printf-подобни log функции, приемащи 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