¿Cuál es la diferencia entre std :: string y std :: basic_string? ¿Y por qué se necesitan ambos?

94

¿Cuál es la diferencia entre std::stringy std::basic_string? ¿Y por qué se necesitan ambos?

Benj
fuente

Respuestas:

63

std::basic_stringes una plantilla de clase para hacer cadenas de tipos de caracteres, std::stringes una typedefplantilla de especialización de esa clase para char. Sí, ambos son necesarios (o al menos requeridos por el estándar).

CB Bailey
fuente
17
¿Por qué ambos son necesarios?
Mohamed El-Nakib
1
entonces estás diciendo que std :: string es typedef std :: basic_string <char> std :: string?
unresolved_external
1
@MuhammadAnnaqeeb 2.5 años tarde, pero la respuesta corta es proporcionar soporte de cadena ancha (wstring) (Unicode, 2 bytes por carácter, wchar_t) también.
Andrew
46

std::stringes una instanciación de std::basic_string<T>:

typedef std::basic_string<char> string

std::basic_stringEs necesario tener una interfaz similar para todo tipo de cadenas ( wstringpor ejemplo).

pmr
fuente
33
El término adecuado es "especialización". stringes una especialización de basic_string.
el AnT
3
Supongo que podrías discutir sobre eso. "especialización" se usa generalmente para indicar herencia. Se crea una instancia de una {clase | función} con plantilla sustituyendo los argumentos de la plantilla. Hay una especialización de plantilla parcial, pero no se usa aquí.
pmr
5
Hacer referencia a una clase derivada como una "especialización" es un uso menos formal de "especialización". La palabra 'especialización' no se usa así en absoluto en el estándar (estoy bastante seguro), pero se usa ampliamente para describir la especialización de plantillas. El nombre de una especialización de plantilla se puede utilizar en contextos que no fuerzan ni la instanciación implícita, por lo que la especialización y la instanciación son conceptos separados. Además de una especialización de plantilla (el nombre de una plantilla con un conjunto particular de parámetros), también hay especializaciones parciales (solo plantillas de clase) y especializaciones explícitas.
CB Bailey
1
Usar "especialización" aquí sería engañoso. Una especialización de plantilla tiene un significado específico (no relacionado con la herencia), pero eso NO es lo que se usa aquí. std :: string no es ni más ni menos que typedef, como: namespace std { typedef basic_string<char> string; }Técnicamente, tampoco es realmente una instanciación, pero al menos está más cerca (la instanciación, por definición, crea una instancia, y una typedef solo crea un nombre, no una instancia ).
Jerry Coffin
3
@Charles: es engañoso porque (con las plantillas), "especialización" normalmente se refiere a una especialización parcial o una especialización explícita, no a un typedef para lo que terminará como una simple instanciación.
Jerry Coffin
17

A std::stringes una instanciación de la std::basic_stringplantilla con un tipo de char. Necesita ambos para poder hacer cadenas de cosas además char, como std::basic_string<wchar_t>una cadena de caracteres anchos. O si quieres una cadena con elementos de 32 bits, std::basic_string<unsigned int>.

Zanson
fuente
2
Creo que esta debería ser la respuesta más votada. Proporciona un caso de uso en el que no podría crear std::basic_stringuna instancia sin un chartipo.
hlin117