stringstream :: str copia de duración

Algo que muchos progtwigdores de C ++ extrañan (lee: yo) cuando usa stringstream s por primera stringstream es el hecho de que la copia devuelta por stringstream::str() es temporal, que dura hasta el final de la expresión en la que se usa. Sin embargo, no entiendo

  1. Cómo se hace esto. Buscando en el encabezado de sstream para libstdc ++, solo veo una copia hecha y devuelta. ¿Cómo se restringe la vida útil?
  2. Por qué este es el comportamiento deseado, especialmente porque es un problema tan común. Si se hace una copia de todos modos, ¿por qué no puedo apropiarme de ella?

Tenga en cuenta que esto no es un duplicado de cadena de caracteres, cadena y confusión de conversión de caracteres * . Eso va explicando el comportamiento y las soluciones; Estoy buscando mecánica y razonamiento.

Esto no es un problema de stringstream de stringstream . Es el problema de la función c_str : devuelve el puntero a una representación char* de std::string , pero vive solo durante la vida útil de una cadena original. Cuando llama a char *str = ss.str().c_str() realidad ocurre lo siguiente:

 string tmp = ss.str(); char *str = tmp.c_str(); tmp.~string (); // after that line the pointer `str` is no longer valid 

c_str es una función peligrosa que se proporciona solo con fines de compatibilidad y velocidad, y debe evitar su uso.

stringstream::str() devuelve una string . Período. Lo hace por valor, por lo que puede hacer lo que quiera con él (por ejemplo, tomar posesión).

¿Cómo se hace esto? Buscando en el encabezado de sstream para libstdc ++, solo veo una copia hecha y devuelta. ¿Cómo se restringe la vida útil?

str() devuelve por valor, lo que significa que el objeto que devuelve se destruye al final de la expresión completa. Es simplemente la forma en que funcionan los temporarios.

Por qué este es el comportamiento deseado, especialmente porque es un problema tan común. Si se hace una copia de todos modos, ¿por qué no puedo apropiarme de ella?

Es una enmienda de los tradicionales IOStreams. La antigua clase obsoleta de secuencias strstream tenía un método str() que devolvía un puntero a su búfer interno. Para protegerse contra la invalidación del puntero, el flujo tuvo que estar “congelado”, lo que significa que el búfer no pudo ser redimensionado.

El IOStreams estándar devuelve una copia del búfer como un objeto std::basic_string para que ya no sea necesario congelar el flujo.