problema de retorno temporário de stringstream ostream
Estou criando um logger com as seguintes seções:
// #define LOG(x) // for release mode
#define LOG(x) log(x)
log(const string& str);
log(const ostream& str);
Com a ideia de fazer:
LOG("Test");
LOG(string("Testing") + " 123");
stringstream s;
LOG(s << "Testing" << 1 << "two" << 3);
Isso tudo funciona como pretendido, mas quando eu faço:
LOG(stringstream() << "Testing" << 1 << "two" << 3);
Não funciona:
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;
}
}
resulta em "formato" contendo dados indesejados em vez da string correta usual.
Eu acho que isso é porque o ostream temporário retornado pelo operador << sobrevive ao fluxo de strings de onde ele vem.
Ou eu estou errado?
(Por que o string () funciona dessa maneira? É porque retorna uma referência a si mesmo? Estou assumindo que sim.)
Eu realmente gostaria de fazer desta forma, pois eu estaria eliminando uma alocação adicional ao fazer o login no modo de liberação.
Quaisquer ponteiros ou truques para fazê-lo desta forma seriam bem-vindos. Na minha solução atual eu tenho muitas funções de log diferentes e elas são todas mais complexas do que isso. Então, eu preferiria que isso fosse implementado de alguma forma no código de chamada. (E não modificando meu #define se possível)
Só para dar uma ideia, um exemplo de uma das minhas #definas reais:
#define LOG_DEBUG_MSG(format, ...) \
LogMessage(DEBUG_TYPE, const char* filepos, sizeof( __QUOTE__( @__VA_ARGS__ )), \
format, __VA_ARGS__)
que corresponde a funções de log do tipo varargs printf, tendo char *, string () e ostream (), bem como funções não-vararg, tendo string (), exception () e HRESULT.