Me parece que muchas bibliotecas C ++ más grandes terminan creando su propio tipo de cadena. En el código de cliente que o bien tiene que usar el uno de la biblioteca ( QString
, CString
, fbstring
etc., estoy seguro de que nadie puede nombrar algunos) o mantener la conversión entre el tipo estándar y el que utiliza la biblioteca (que la mayoría de las veces implica al menos una copia).
Entonces, ¿hay algún error en particular o algo malo std::string
(al igual que la auto_ptr
semántica era mala)? ¿Ha cambiado en C ++ 11?
java.lang.String
(falta de sobrecarga del operador, etc.) dificultaría el uso de cualquier otra cosa.Respuestas:
La mayoría de esas bibliotecas C ++ más grandes se iniciaron antes de que
std::string
se estandarizara. Otros incluyen características adicionales que se estandarizaron tarde o que aún no se estandarizaron, como el soporte para UTF-8 y la conversión entre codificaciones.Si esas bibliotecas se implementaran hoy, probablemente elegirían escribir funciones e iteradores que operen en
std::string
instancias.fuente
char
se garantiza que es lo suficientemente grande como para contener cualquier punto de código UTF-8. AFAIK, ese es el único "soporte" que proporcionó C ++ 98.wchar_t
que no es lo suficientemente grande como para representar todos los puntos de código Unicode. Además, hubo toda esta discusión sobre UTF-16 considerada dañina donde se hizo el argumento convincente de que UTF-8 debería usarse exclusivamente ...String es la gran vergüenza de C ++.
Durante los primeros 15 años, no proporciona una clase de cadena en absoluto, lo que obliga a cada compilador en cada plataforma y a cada usuario a crear la suya propia.
Luego crea algo que está confundido acerca de si se supone que es una API de manipulación de cadena completa o solo un contenedor de caracteres STL, con algunos algoritmos que duplican los de un std :: Vector o son diferentes.
Cuando una operación de cadena obvia como replace () o mid () involucra un lío de iteradores que necesita introducir una nueva palabra clave 'auto' para mantener la declaración adecuada en una sola página y hace que la mayoría de las personas se rindan en todo el idioma .
Y luego tienes unicode 'support' y std :: wstring que es solo arghh .....
<despotricar> gracias - Me siento mucho mejor ahora.
fuente
std::string
. La falta de una clase String en 1983 no justifica tener más de ellos ahora.En realidad ... hay varios problemas con
std::string
, y sí, mejora un poco en C ++ 11, pero no nos adelantemos.QString
yCString
son parte de antiguas bibliotecas, por lo tanto, existían antes de que C ++ se estandarizara (al igual que el SGI STL). Por lo tanto, tuvieron que crear una clase.fbstring
abordar preocupaciones de rendimiento muy específicas. El estándar prescribe una interfaz y la complejidad algorítmica garantiza mínimos, sin embargo, es una calidad de detalles de implementación si esto termina siendo rápido o no.fbstring
tiene optimizaciones específicas (relacionadas con el almacenamiento, o más rápido,find
por ejemplo).Otras preocupaciones que no fueron evocadas aquí (en vrac):
std::string
está codificando sin darse cuenta, y no tiene un código especial para UTF-8, es fácil almacenar una cadena UTF-8 y corromperla inadvertidamentestd::string
la interfaz está hinchada , muchos métodos podrían haberse implementado como funciones libres y muchos están duplicados para conformar tanto una interfaz basada en índice como una interfaz basada en iterador.fuente
c_str()
devuelve un puntero al almacenamiento contiguo, lo que proporciona cierta interoperabilidad en C. Sin embargo, no puede modificar los datos apuntados. Las soluciones típicas incluyen el uso de avector<char>
.&s[0]
ya no importa :)&s[0]
puede no apuntar a una cadena terminada en NUL (a menos quec_str()
se haya llamado desde la última modificación).c_str()
Devuelve: Un punterop
tal quep + i == &operator[](i)
para cadai
en[0,size()]
".Además de las razones publicadas aquí, también hay otra: la compatibilidad binaria . Los escritores de las bibliotecas no tienen control sobre qué
std::string
implementación está utilizando y si tiene el mismo diseño de memoria que el suyo.std::string
es una plantilla, por lo que su implementación se toma de sus encabezados STL locales. Ahora imagine que está utilizando localmente alguna versión STL de rendimiento optimizado, totalmente compatible con el estándar. Por ejemplo, puede haber optado por introducir intrusiones en el búfer estático en cada unostd::string
para reducir el número de asignaciones dinámicas y errores de caché. Como resultado, el diseño de la memoria y / o el tamaño de su implementación es diferente al de la biblioteca.Si solo el diseño es diferente, algunas
std::string
llamadas de función de miembro en instancias pasadas de la biblioteca al cliente o al revés pueden fallar, dependiendo de qué miembros se desplazaron.Si el tamaño también es diferente, todos los tipos de biblioteca que tienen
std::string
miembro parecerán tener un tamaño diferente cuando se verifican en la biblioteca y en el código del cliente. Los miembros de datos que siguen alstd::string
miembro también tendrán desplazamientos desplazados, y cualquier acceso directo / acceso en línea llamado desde el cliente devolverá basura, a pesar de "estar bien" al depurar la propia biblioteca.En pocas palabras: si la biblioteca y el código del cliente se compilan contra diferentes
std::string
versiones, se vincularán perfectamente, pero puede dar lugar a algunos errores desagradables y difíciles de entender. Si cambia sustd::string
implementación, todas las bibliotecas que exponen miembros de STL deben volver a compilarse para que coincidan con elstd::string
diseño del cliente . Y debido a que los programadores quieren que sus bibliotecas sean robustas, rara vez se verástd::string
expuesto en alguna parte.Para ser justos, esto se aplica a todos los tipos de STL. IIRC no tienen un diseño de memoria estandarizado.
fuente
Hay muchas respuestas a la pregunta, pero aquí hay algunas:
Legado. Muchas bibliotecas y clases de cadenas se escribieron ANTES de la existencia de std :: string.
Por compatibilidad con el código en C. La biblioteca std :: string es C ++ donde hay otras bibliotecas de cadenas que funcionan con C y C ++.
Para evitar asignaciones dinámicas. La biblioteca std :: string utiliza asignación dinámica y puede no ser adecuada para sistemas integrados, interrupción o código relacionado en tiempo real, o para funcionalidad de bajo nivel.
Plantillas. La biblioteca std :: string se basa en plantillas. Hasta hace poco, varios compiladores de C ++ tenían un rendimiento de plantilla deficiente o incluso defectuoso. Desafortunadamente, trabajo en una industria que usa muchas herramientas personalizadas y una de nuestras cadenas de herramientas de un jugador importante en la industria no admite "oficialmente" el 100% de C ++ (con elementos defectuosos que son plantillas y otros).
Probablemente hay muchas más razones válidas también.
fuente
Se trata principalmente de Unicode. El soporte estándar para Unicode es abismal en el mejor de los casos, y todos tienen sus propias necesidades de Unicode. Por ejemplo, ICU admite todas las funcionalidades de Unicode que pueda desear, detrás de la interfaz más desagradable generada automáticamente desde Java que pueda imaginar, y si está en Unix atascado con UTF-16 puede que no sea su idea de un buen momento.
Además, muchas personas necesitan diferentes niveles de soporte Unicode, no todos necesitan las complejas API de diseño de texto y esas cosas. Por lo tanto, es fácil ver por qué existen numerosas clases de cadenas: la estándar es bastante mala y todos tienen diferentes necesidades que las nuevas, sin que nadie logre crear una sola clase que pueda realizar muchas plataformas multiplataforma de soporte Unicode con una interfaz agradable.
En mi opinión, esto es principalmente culpa del Comité C ++ por no proporcionar correctamente el soporte para Unicode- en 1998 o 2003, tal vez fue comprensible, pero no en C ++ 11. Esperemos que en C ++ 17 les vaya mejor.
fuente
Esto se debe a que cada programador tiene algo que demostrar y siente la necesidad de crear su propia clase de cadena más rápida e increíble para su única función. Por lo general, es un poco superfluo y, en mi experiencia, conduce a todo tipo de conversiones de cadenas adicionales.
fuente