std :: string :: c_str () y temporales

Es el siguiente código de C ++ bien formado:

void consumer(char const* p) { std::printf("%s", p); } std::string random_string_generator() { // returns a random std::string object } consumer(random_string_generator().c_str()); 

El problema que tengo es que, después de crear el objeto std :: string temporal y tomar el puntero c_str (), nada impide que se destruya el objeto std :: string (¿o quizás estoy equivocado?). ¿Puede indicarme el estándar, si el código es correcto a pesar de todo? Funciona, cuando pruebo con g ++.

El puntero devuelto por std::string::c_str() apunta a la memoria mantenida por el objeto de cadena. Permanece válido hasta que se invoca una función no const en el objeto de cadena o se destruye el objeto de cadena. El objeto de cadena que le preocupa es temporal. Será destruido al final de la expresión completa, no antes y no después. En su caso, el final de la expresión completa es después de la llamada al consumer , por lo que su código es seguro. No sería si el consumer guardara el puntero en alguna parte, con la idea de usarlo más tarde.

La duración de los temporales ha sido estrictamente definida desde C ++ 98. Antes de eso, variaba, dependiendo del comstackdor, y el código que ha escrito no habría funcionado con g ++ (antes de 1995, aproximadamente g ++ lo cambió casi de inmediato cuando el comité de estándares lo votó). (Tampoco había una std::string , pero los mismos problemas afectan a cualquier clase de cadena escrita por el usuario).

La vida útil del std::string temporal se extiende un poco más allá del punto donde el consumer regresa, por lo que es seguro usar cualquier cosa en esa cadena directamente desde el consumer . Lo que no está bien es almacenar el valor que devuelve c_str e intentar usarlo más tarde (el temporal se habrá destruido, y solo podemos adivinar lo que encontrará en el otro extremo del puntero).

El temporal devuelto por la función random_string_generator () se puede usar en la función consumer () de forma segura.