Jaka jest różnica między std :: string a std :: basic_string? Dlaczego oba są potrzebne?

95

Jaka jest różnica między std::stringi std::basic_string? Dlaczego oba są potrzebne?

Benj
źródło

Odpowiedzi:

62

std::basic_stringto szablon klasy służący do tworzenia łańcuchów z typów znaków, std::stringsłuży typedefdo specjalizacji tego szablonu klasy dla char. Tak, oba są potrzebne (lub przynajmniej wymagane przez standard).

CB Bailey
źródło
18
dlaczego oba są potrzebne?
Mohamed El-Nakib,
1
więc mówisz, że std :: string to typedef std :: basic_string <char> std :: string?
unresolved_external
2
@MuhammadAnnaqeeb 2,5 roku spóźnienie, ale krótką odpowiedzią jest zapewnienie obsługi szerokich ciągów (wstring) (Unicode, 2 bajty na znak, wchar_t).
Andrew
50

std::stringjest instancją std::basic_string<T>:

typedef std::basic_string<char> string

std::basic_stringKonieczne jest posiadanie podobnego interfejsu dla wszystkich typów ciągów ( wstringna przykład).

pmr
źródło
33
Właściwy termin to „specjalizacja”. stringjest specjalizacja z basic_string.
AnT
3
Myślę, że można by się o to spierać. „specjalizacja” jest zwykle używana do wskazania dziedziczenia. Utworzona na podstawie szablonu {funkcja | funkcja} jest tworzona przez podstawienie argumentów szablonu. Istnieje częściowa specjalizacja szablonów, ale nie jest ona tutaj używana.
pmr
5
Odwołanie się do klasy pochodnej jako „specjalizacji” jest mniej formalnym zastosowaniem terminu „specjalizacja”. Słowo „specjalizacja” nie jest w ogóle używane w standardzie (jestem tego całkiem pewien), ale jest szeroko stosowane do opisania specjalizacji szablonów. Nazwy specjalizacji szablonu można używać w kontekstach, które nie wymuszają ani niejawnych instancji, więc specjalizacja i tworzenie instancji to osobne pojęcia. Oprócz specjalizacji szablonowej (nazwa szablonu z określonym zestawem parametrów) istnieją również specjalizacje częściowe (tylko szablony klas) i specjalizacje jawne.
CB Bailey
1
Używanie tutaj terminu „specjalizacja” byłoby mylące. Specjalizacja szablonu ma określone znaczenie (niezwiązane z dziedziczeniem), ale NIE jest to to, co zostało tutaj użyte. std :: string to nic innego jak typedef, na przykład: namespace std { typedef basic_string<char> string; }Technicznie nie jest to też tak naprawdę instancja, ale jest przynajmniej bliższa (instancja z definicji tworzy instancję, a typedef tworzy tylko nazwę, a nie instancję ).
Jerry Coffin
3
@Charles: to mylące, ponieważ (w przypadku szablonów) „specjalizacja” zwykle odnosi się do częściowej specjalizacji lub jawnej specjalizacji, a nie do definicji typu, która kończy się jako prosta instancja.
Jerry Coffin
19

A std::stringjest instancją std::basic_stringszablonu z typem char. Potrzebujesz obu, aby oprócz tego móc tworzyć ciągi rzeczy char, na przykład std::basic_string<wchar_t>ciąg szerokich znaków. Lub jeśli chcesz ciąg z 32 bitowych elementów std::basic_string<unsigned int>.

Zanson
źródło
2
Myślę, że to powinna być najczęściej głosowana odpowiedź. Zapewnia przypadek użycia, w którym nie można utworzyć wystąpienia std::basic_stringbez chartypu.
hlin117
0

Tylko mały dodatek do tego, co wszyscy odpowiedzieli. Podobnie jak std::stringjego specjalizacja basic_string, również domyślnie niektóre inne parametry oprócz typu char. Basic_string może mieć niestandardowy typ znaku (np. Basic_string może mieć wide_chars), niestandardową cechę char_trait (np. Basic_string może mieć szerokie znaki, ale obsługuje każdą operację normalnych znaków) i niestandardowy alokator (basic_string może zawierać dodatkowe informacje dla niestandardowego debuggera lub zarządzania pamięcią statyczną).

Przydatność

W std::stringdomyślnie wszystkie te parametry do rozsądnych wartości, jak w większości przypadków tylko potrzebować std::stringi to jest jego przydatność. Z drugiej strony, gdy potrzebujesz czegoś bardziej niestandardowego, masz std::basic_string. Więc oba mają różne cele

Spyros Mourelatos
źródło