sstream print mystr español biblioteca c++ stringstream

c++ - print - stringstream java



¿Cómo inicializar un std:: stringstream? (2)

El stringbuf debe inicializarse antes de que se le puedan agregar valores. stringstream es un objeto.

Haciendo:

std::stringstream ss;

Básicamente, está permitiendo que la aplicación asigne espacio para manejar los valores que se agregarán.

Necesito concatenar una cadena con enteros. Para hacer eso estoy usando stringstream de la siguiente manera:

int numPeople = 10; stringstream ss; ss << "Number of people is " << numPeople;

Y eso funcionó. Pero estaba tratando de hacerlo de la siguiente manera:

int numPeople = 10; stringstream ss << "Number of people is " << numPeople;

Y estaba recibiendo el siguiente error: " inicializador esperado antes del token ''<<'' "

¿Por qué estaba recibiendo este error? ¿Por qué no puedo asignar el valor de stringstream al mismo tiempo que lo declaro?


stringstream ss << "Number of people is " << numPeople;

¿Por qué no puedo asignar el valor de stringstream al mismo tiempo que lo declaro?

Esto es similar a la esperanza de que esto funcionaría:

int x + 3 + 9;

El problema

Cuando define y otorga un valor a un objeto, C ++ le permite llamar al constructor, que requiere una lista de expresiones separadas por comas. Por conveniencia, la Type variable = value; la notación es eluida para llamar a Type variable(value); , pero solo funciona para un solo valor.

Para int , puedes corregir fácilmente el código:

int x = 3 + 9;

... y funciona porque "3 + 9" se puede evaluar de forma independiente primero para dar un valor razonable para almacenar en x . El comportamiento del compilador para operator + on int s hace lo que queremos : produce el resultado int que luego queremos almacenar en x . Pero si lo intentas para stringstream ...

stringstream ss = "Number of people is " << numPeople; // BROKEN

... no funcionará, porque "Number of people is " << numPeople gente debe ser evaluada primero, pero es ilegal; error C2296: ''<<'' : illegal, left operand has type ''const char [20]'' un error como " error C2296: ''<<'' : illegal, left operand has type ''const char [20]'' ": no proporcionará un valor útil para el constructor de stringstream . El problema es que el compilador sigue intentando aplicar el operador de cambio a nivel de bits, lo que solo tiene sentido para los números, ya que las sobrecargas para << que ostream& aplicar requieren un argumento de la izquierda del tipo ostream& . C ++ requiere que el valor que se evalúa a la derecha de = se evalúe independientemente de la asignación que finalmente se realice con el valor resultante, y en ese punto el tipo de la variable que se está construyendo no es relevante para la forma en que se intenta la evaluación en la expresión asignado

Una solución

Es un problema un poco de gallina y huevo aquí, porque de alguna manera necesitas combinar los valores de la mano derecha que deseas en la stringstream de stringstream para llamar al stringstream la stringstream de stringstream , pero para eso necesitas ... una stringstream . En realidad, puedes stringstream con una stringstream temporal:

static_cast<std::ostringstream&&>(std::ostringstream() << "Number of people is " << numPeople)

Desafortunadamente, la stringstream es necesaria porque el operator<< sobrecargas manejan las stringstream a través de las referencias a su clase base ostream , devolviendo un ostream& , por lo tanto, debe volver al tipo de stringstream manualmente, por lo que puede invocar el constructor de movimientos std::stringstream ...

La construcción completa de una sola línea es entonces ...

std::stringstream ss(static_cast<std::ostringstream&&>(std::ostringstream() << "Number of people is " << numPeople));

... pero eso es demasiado horrible para contemplar.

Haciendo la solución (posiblemente) menos horrible

Dependiendo de tus sensibilidades, puedes sentir que una macro ayuda o es peor ...

#define OSS(VALUES) / static_cast<std::ostringstream&&>(std::ostringstream() << VALUES) std::stringstream ss(OSS("Number of people is " << numPeople));

FWIW, también puedes usar la macro para crear cadenas ...

std::string s(OSS("Number of people is " << numPeople).str());

Una (posiblemente) mejor práctica

Simplemente cree la stringstream (opcionalmente, proporcione una string única al constructor) y luego use el operator<< en una segunda declaración:

std::stringstream ss; ss << "Number of people is " << numPeople;

Esto es mucho más fácil de leer. Con la construcción de movimientos, después de la optimización es probable que no haya razones de rendimiento para preferir dos declaraciones.

Una alternativa

C ++ 11 introdujo las sobrecargas de to_string() que son convenientes si tiene un valor integral o dos para concatenar con o en una string :

std::string s = "Number of people is " + std::to_string(numPeople);

Sin embargo, esto puede ser ineficiente (compruebe las capacidades de optimización de su compilador (es) si le importa): es probable que cada std::to_string() asigne dinámicamente un búfer para una instancia de std::string independiente, entonces las concatenaciones individuales pueden implicar una copia adicional de texto, y los buffers asignados dinámicamente originales pueden necesitar ser ampliados, entonces la mayoría de esas std::string s temporales tomarán tiempo para desasignarse durante la destrucción.

Fue peor en C ++ 03

C ++ 03 carecía de constructores de movimientos, por lo que era necesario usar la función miembro std::ostringstream::str() en el temporal para obtener una copia adicional de la std::string con la que construir el stringsteam denominado. ..

stringstream ss(static_cast<std::ostringstream&>(std::ostringstream() << "Number of people is " << numPeople).str());

Con este código C ++ 03, existe la posibilidad de duplicar las asignaciones de memoria dinámica y una copia del contenido, por lo que la construcción seguida de la transmisión por secuencias fue una apuesta mejor.