Pregunta

Esto no es una cuestión de diseño, realmente, a pesar de que parece.(Bueno, es una cuestión de diseño).Lo que me pregunto es por qué el C++ std::fstream las clases no tome una std::string en su constructor o métodos abiertos.Todo el mundo ama los ejemplos de código así:

#include <iostream>
#include <fstream>
#include <string>

int main()
{
    std::string filename = "testfile";      
    std::ifstream fin;

    fin.open(filename.c_str()); // Works just fine.
    fin.close();

    //fin.open(filename); // Error: no such method.
    //fin.close();
}

Esto me pone todo el tiempo cuando se trabaja con archivos.Seguramente la biblioteca de C++ usaría std::string siempre que sea posible?

¿Fue útil?

Solución

Tomando una cadena C de C++03 std::fstream clase disminución de la dependencia de la std::string clase.En C++11, sin embargo, la std::fstream clase no permiten pasar de un std::string por su parámetro del constructor.

Ahora, usted puede preguntarse por qué no hay una conversión transparente de un std:string para una cadena C, de modo que una clase que espera una cadena C aún podría tardar un std::string como una clase que espera un std::string puede tomar una C de la cadena.

La razón es que esto podría causar un ciclo de conversión, que a su vez puede conducir a problemas.Por ejemplo, supongamos que std::string sería convertible en una cadena C de modo que usted puede utilizar std::strings con fstreams.Supongamos también que la cadena C son convertibles a std::strings como es el estado en el estándar actual.Ahora, considere lo siguiente:

void f(std::string str1, std::string str2);
void f(char* cstr1, char* cstr2);

void g()
{
    char* cstr = "abc";
    std::string str = "def";
    f(cstr, str);  // ERROR:  ambiguous
}

Porque se puede convertir en ambos sentidos entre un std::string y una cadena C de la llamada a f() podría resolver a cualquiera de los dos f() alternativas, y por lo tanto es ambigua.La solución es romper el ciclo de conversión a una dirección de la conversión explícita, que es lo que la STL eligió hacer con c_str().

Otros consejos

Hay varios lugares donde el estándar de C++ comité no realmente optimizar la interacción entre las instalaciones de la biblioteca estándar.

std::string y su uso en la biblioteca es uno de estos.

Otro ejemplo es std::swap.Muchos de los recipientes tienen una función de miembro intercambio, pero sin sobrecarga de std::swap se suministra.Lo mismo va para los std::sort.

Espero que todas estas pequeñas cosas se fija en la próxima estándar.

Tal vez es un consuelo:todos fstream han conseguido un open(const string &, ...) junto al open(const char *, ...) en el borrador de trabajo de C++0x estándar.(ver, por ejemplo,27.8.1.6 para la basic_ifstream declaración)

Por lo que cuando se finalizó y se lleva a la práctica, no más :)

La corriente IO de la biblioteca ha sido añadido a la biblioteca estándar de C++ antes de la STL.Con el fin de no romper la compatibilidad hacia atrás, se ha decidido para evitar la modificación de la IO en la biblioteca cuando la STL se agrega, incluso si eso significaba algunos problemas como el que ustedes plantean.

@ Bernardo:
Monolitos "Mismo." "Todos para uno y uno para todos" puede trabajar para Mosqueteros, pero no funciona tan bien para los diseñadores de clase.He aquí un ejemplo que no es del todo ejemplar, y que ilustra lo mal que puede ir mal cuando el diseño se convierte en diseños demasiado sofisticados.El ejemplo es, por desgracia, tomado de una biblioteca estándar cerca de usted...~ http://www.gotw.ca/gotw/084.htm

Es irrelevante, lo que es verdadero.¿Qué quieres decir con std::string interfaz de ser grande?Lo que hace grande significa, en este contexto - un montón de llamadas de método?No estoy siendo bromista, estoy realmente interesado.

Tiene más métodos que realmente necesita, y el comportamiento de la utilización integral de los desplazamientos en lugar de iteradores es un poco dudoso (como sería contrario a la forma en que el resto de la biblioteca de obras).

El verdadero problema creo que es que la biblioteca de C++ consta de tres partes;tiene la antigua biblioteca de C, se tiene la STL, y tiene cuerdas-y-iostreams.Aunque se hicieron algunos esfuerzos para integrar las diferentes partes (por ejemplo,la adición de sobrecargas a la biblioteca de C, ya que C++ soporta la sobrecarga;la adición de iteradores para basic_string;la adición de la iostream iterador los adaptadores), hay un montón de incoherencias cuando se mira en el detalle.

Por ejemplo, basic_string incluye métodos que son innecesarios, duplicados de algoritmos estándar;los diferentes métodos de búsqueda, probablemente podría extraerse de forma segura.Otro ejemplo:configuraciones utilizan raw punteros en lugar de iteradores.

C++ creció en máquinas más pequeñas que los monstruos podemos escribir el código para el día de hoy.De vuelta al iostream era nuevo, muchos desarrolladores que realmente le importaba el tamaño del código (que tenía que caber todo el programa y los datos en varios cientos de KB).Por lo tanto, muchos no quieren tirar en la "gran" cadena C++ biblioteca.Muchos ni siquiera el uso de la biblioteca iostream por las mismas razones, el tamaño del código.

No teníamos miles de megabytes de RAM para tirar todo como lo hacemos hoy.Nosotros generalmente no tienen nivel de función de la vinculación, así que estaban a merced de que el desarrollador de la biblioteca para uso de un montón de objeto independiente archivos o bien tirar toneladas de fuera de lugar del código.Todo esto FUD hecho los desarrolladores de alejarse de std::string.

Entonces yo evitarse std::string demasiado."Demasiado hinchado", "llamada a malloc demasiado a menudo", etc.Tontamente utilizando basado en pila de búferes para las cadenas, a continuación, añadir todo tipo de tedioso código para asegurarse de no saturación.

Es allí cualquier clase en STL, que toma una cadena...Yo no lo creo (no podía encontrar ninguna en mi búsqueda rápida).Así que es probable que algunos decisión de diseño, que no hay clase en STL debe ser dependiente de cualquier otra clase STL (que no es directamente necesario para la funcionalidad).

Creo que esto ha sido pensado y que se hizo para evitar la dependencia;es decir,#include <fstream> no debe forzar una #include <string>.

Para ser honesto, esto parece bastante intrascendentes problema.Una mejor pregunta sería, ¿por qué es std::string interfaz tan grande?

Hoy en día este problema se puede solucionar muy fácilmente:agregar -std=c++11 a su CFLAGS.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top