С++ 20 с u8, char8_t и std :: string - программирование

С++ 20 с u8, char8_t и std :: string

С++ 11 принес нам префикс u8 для литералов UTF-8, и я подумал, что это было круто несколько лет назад, и наполнил мой код такими вещами:

std::string myString = u8"●";

Это все хорошо и хорошо, но проблема возникает в С++ 20, он, кажется, больше не компилируется, потому что u8 создает char8_t *, и это несовместимо с std :: string, которая просто использует char.

Должен ли я создавать новую строку utf8? Какой последовательный и правильный способ сделать это в мире С++ 20, где у нас есть более явные типы, которые не соответствуют стандартному std :: string?

4b9b3361

Ответ 1

В дополнение к ответу @lubgr в статье char8_t исправление обратной совместимости (P1423) обсуждается несколько способов создания std::string с символьными массивами char8_t.

По сути, идея заключается в том, что вы можете u8 массив u8 char в "обычный" массив char, чтобы получить то же поведение, что и в С++ 17, и раньше вам просто нужно быть немного более явным. В статье рассматриваются различные способы сделать это.

Вероятно, наиболее простым (но не полностью нулевым, если вы не добавляете больше перегрузок) метод, который соответствует вашему сценарию использования, является последний, то есть введение явных функций преобразования:

std::string from_u8string(const std::string &s) {
  return s;
}
std::string from_u8string(std::string &&s) {
  return std::move(s);
}
#if defined(__cpp_lib_char8_t)
std::string from_u8string(const std::u8string &s) {
  return std::string(s.begin(), s.end());
}
#endif

Ответ 2

Должен ли я создавать новую строку utf8?

Нет, это уже там. P0482 предлагает не только char8_t, но и новую специализацию std::basic_string для char8_t символов char8_t именем std::u8string. Так что это уже компилируется с помощью clang и libc++ из trunk:

const std::u8string str = u8"●";

Тот факт, что конструкция std::string из u8 -literal обрывается, вызывает сожаление. Из предложения:

Это предложение не указывает никаких функций обратной совместимости, кроме как для сохранения интерфейсов, которые оно устарело. Отсутствие таких функций не связано с убеждением, что функции обратной совместимости не нужны. Автор считает, что такие функции необходимы, но временные ограничения не позволили адекватно исследовать, какие проблемы необходимо решать, в какой степени они должны решаться и как эти функции должны быть указаны. [...]

Но я полагаю, что большая часть такой инициализации, как указано выше, должна быть grep -able или подвергаться каким-либо автоматическим исправлениям инструментов clang.