Std:: u16string, std:: u32string, std::string, length(), size(), кодовые точки и символы
Я рад видеть std::u16string
и std::u32string
в С++ 11, но мне интересно, почему нет std::u8string
для обработки дела UTF-8. У меня создается впечатление, что std::string
предназначен для UTF-8, но, похоже, это не очень хорошо. Я имею в виду, не возвращает ли std::string.length()
размер буфера строк, а не количество символов в строке?
Итак, как метод length()
стандартных строк, определенных для новых классов С++ 11? Они возвращают размер строкового буфера, количество кодовых точек или количество символов (если суррогатная пара - 2 кодовых пункта, но один символ. Пожалуйста, поправьте меня, если я ошибаюсь)?
А как насчет size()
; Разве это не равно length()
?
См. http://en.cppreference.com/w/cpp/string/basic_string/length для источника моей путаницы.
Итак, я думаю, мой основной вопрос: как использовать std::string
, std::u16string
и std::u32string
и правильно различать размер буфера, количество кодовых точек и количество символов? Если вы используете стандартные итераторы, выполняете ли вы итерацию по байтам, кодовым точкам или символам?
Ответы
Ответ 1
u16string
и u32string
не являются "новыми С++ 11 классами". Они всего лишь typedefs std::basic_string
для char16_t
и cha32_t
типов.
length
всегда равен size
для любого basic_string
. Это число T
в строке, где T
- тип шаблона для basic_string
.
basic_string
не является Unicode в любом случае, форме или форме. В нем нет понятия кодовых точек, графем, символов Юникода, нормализации Юникода или чего-либо подобного. Это просто упорядоченная последовательность T
s. Единственное, что известно Unicode о u16string
и u32string
, это то, что они используют тип, возвращаемый литералами u""
и u""
. Таким образом, они могут хранить строки в кодировке Unicode, но они ничего не делают, что требует знания указанной кодировки.
Итераторы перебирают элементы T
, а не "байты, кодовые точки или символы". Если T
- char16_t
, то он будет перебирать более char16_t
s. Если строка кодируется UTF-16, она выполняет итерацию по кодам UTF-16, а не кодовым точкам Unicode или байтам.
Ответ 2
Все типы строк выполняют одно и то же: они содержат последовательность элементов, каждый из которых является типом символа для строки. length()
и size()
оба возвращают количество элементов. Итератор итератор по элементам. Более высокий уровень анализа, например, вычисление количества символов, требует гораздо более сложных вычислений.
Ответ 3
В настоящее время нет ничего встроенного в стандарт, чтобы различать единицы кода, кодовые точки или отдельные байты. Тем не менее, похоже, в работе есть некоторые вещи, связанные с такими вещами. В зависимости от того, что решает комитет по стандартам, он может быть частью TR2 или следующего стандарта.