stringstream problema de retorno de secuencia temporal
Estoy creando un registrador con las siguientes secciones:
// #define LOG(x) // for release mode
#define LOG(x) log(x)
log(const string& str);
log(const ostream& str);
Con la idea de hacer:
LOG("Test");
LOG(string("Testing") + " 123");
stringstream s;
LOG(s << "Testing" << 1 << "two" << 3);
Todo esto funciona según lo previsto, pero cuando lo hago:
LOG(stringstream() << "Testing" << 1 << "two" << 3);
No 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;
}
}
da como resultado un 'formato' que contiene datos basura en lugar de la cadena correcta habitual.
Creo que esto se debe a que el ostream temporal devuelto por el operador << sobrevive a la cadena de cadenas de la que proviene.
¿O me equivoco?
(¿Por qué la cadena () funciona de esta manera? ¿Es porque devuelve una referencia a sí misma? Estoy asumiendo que sí.)
Realmente me gustaría hacerlo de esta manera, ya que eliminaría una asignación adicional al iniciar sesión en modo de lanzamiento.
Cualquier puntero o truco para hacerlo de esta manera sería bienvenido. En mi solución real tengo muchas funciones de registro diferentes y todas son más complejas que esto. Así que preferiría tener esto implementado de alguna manera en el código de llamada. (Y no modificando mi #define si es posible)
Solo para dar una idea, un ejemplo de uno de mis #defines reales:
#define LOG_DEBUG_MSG(format, ...) \
LogMessage(DEBUG_TYPE, const char* filepos, sizeof( __QUOTE__( @__VA_ARGS__ )), \
format, __VA_ARGS__)
que coincide con las funciones de registro de varargs printf como con char *, string () y ostream (), así como con las funciones que no son vararg que toman string (), exception () y HRESULT.