В чем разница между std :: string и std :: basic_string? А зачем нужны оба?

94

В чем разница между std::stringи std::basic_string? А зачем нужны оба?

Бендж
источник

Ответы:

63

std::basic_stringэто шаблон класса для создания строк из символьных типов, std::stringэто typedefспециализация этого шаблона класса для char. Да, они оба необходимы (или, по крайней мере, требуются стандартом).

CB Bailey
источник
17
зачем они оба нужны?
Мохамед Эль-Накиб
1
Итак, вы говорите, что std :: string - это typedef std :: basic_string <char> std :: string?
unresolved_external
1
@MuhammadAnnaqeeb с опозданием на 2,5 года, но краткий ответ - обеспечить поддержку широкой строки (wstring) (Unicode, 2 байта на символ, wchar_t).
Эндрю
46

std::stringявляется экземпляром std::basic_string<T>:

typedef std::basic_string<char> string

std::basic_stringнеобходимо иметь аналогичный интерфейс для всех типов строк ( wstringнапример).

pmr
источник
33
Правильный термин - «специализация». stringявляется специализация в basic_string.
AnT 02
3
Думаю, об этом можно поспорить. «специализация» обычно используется для обозначения наследования. Шаблонный {класс | функция} создается путем подстановки аргументов шаблона. Есть частичная специализация шаблона, но здесь она не используется.
pmr
5
Обращение к производному классу как к «специализации» - менее формальное использование термина «специализация». Слово «специализация» вообще не используется в стандарте (я почти уверен), но оно широко используется для описания специализации шаблона. Имя специализации шаблона может использоваться в контекстах, которые не вызывают принудительного и неявного создания экземпляров, поэтому специализация и создание экземпляров являются отдельными понятиями. Помимо специализации шаблона (имя шаблона с определенным набором параметров), существуют также частичные специализации (только для шаблонов классов) и явные специализации.
CB Bailey
1
Использование здесь «специализации» может ввести в заблуждение. Специализация шаблона имеет особое значение (не связанное с наследованием), но это НЕ то, что здесь используется. std :: string - это не что иное, как typedef, например: namespace std { typedef basic_string<char> string; }Технически, это тоже не создание экземпляра, но, по крайней мере, ближе (создание, по определению, создает экземпляр, а typedef создает только имя, а не экземпляр ).
Джерри Коффин,
3
@Charles: это вводит в заблуждение, потому что (с шаблонами) «специализация» обычно относится либо к частичной специализации, либо к явной специализации, а не к определению типов для того, что в конечном итоге будет простым экземпляром.
Джерри Коффин,
17

A std::string- это экземпляр std::basic_stringшаблона с типом char. Вам нужно и то, и другое, чтобы вы могли создавать строки из других вещей char, например, std::basic_string<wchar_t>для строки широких символов. Или , если вы хотите строку с 32 - битными элементами std::basic_string<unsigned int>.

Zanson
источник
2
Я думаю, что это должен быть самый популярный ответ. Он предоставляет вариант использования, когда вы не можете создавать экземпляры std::basic_stringбез charтипа.
hlin117,