2009-11-19 14 views
5

He estado escribiendo un std::streambuf personalizado como parte de un sistema de registro. Sin embargo, tengo problemas con la primera pieza de salida de una transmisión que no está formateada correctamente.std :: ostream no formateo const char * correctamente la primera vez que se usa

Aquí es un caso de prueba reducida que no utiliza ninguna costumbre streambuf o ostream clases:

#include <iostream> 

int main() 
{ 
    std::streambuf *coutbuf = std::cout.rdbuf(); 
    std::ostream(coutbuf) << "test" << ": writing to cout using a separate ostream." << std::endl; 
    return 0; 
} 

Compilación esto usando g ++:

$ g++ --version 
g++ (Ubuntu 4.4.1-4ubuntu8) 4.4.1 

$ g++ -o fail reduced-case.cpp 

$ ./fail 
0x400c80: writing to cout using a separate ostream. 

Tenga en cuenta que la primera cadena literal (prueba " ") se está formateando como un puntero genérico (la dirección de la cadena se envía en hexadecimal), mientras que la segunda cadena literal está formateada correctamente.

Lo único que se me ocurre es que no es válido usar directamente un std::ostream recién construido así (es decir, sin ponerlo en una variable). Si este es el caso, me gustaría saber qué es exactamente lo que lo hace inválido (supongo que no tiene nada que ver con iostremas específicamente, sino más bien con el orden de evaluación o las interacciones con los constructores o algo así). Si ese no es el problema, entonces ¿qué es?

Respuesta

8

El problema es que no debe escribir en un objeto de transmisión temporal. Este:

std::ostream(coutbuf) << "blah"; 

no funciona como se esperaba, ya que el argumento de la izquierda para operator<<() es un valor de lado derecho. Sin embargo, todos los operadores sobrecargados como una función libre de tomar una referencia no const a una corriente como su argumento de la izquierda:

std::ostream& operator<<(std::ostream&, ...); 

Desde rvalues ​​no se unen a las referencias no constante, que no pueden ser llamados.

que sospecha que su aplicación std lib implementa << para const char* como una función libre y tiene por lo tanto volver a caer en cierta << que es un miembro de std::ostream. Parece en su implementación que es el que da salida a cualquier puntero como void*.

En pocas palabras: no intente escribir en objetos de transmisión temporal.

1

No puede usar un objeto de transmisión temporal como este. Dale un nombre a la variable temporal.

#include <iostream> 

int main() 
{ 
    std::streambuf *coutbuf = std::cout.rdbuf(); 
    std::ostream os(coutbuf); 
    os << "test" << ": writing to cout using a separate ostream." << std::endl; 
    return 0; 
} 
Cuestiones relacionadas