Я занимаюсь обновлением своей кодовой базы до C ++ 20 и хочу использовать std::u8string / char8_t. Я использую стороннюю библиотеку, которая принимает и возвращает строки UTF-8 в своем API, однако она еще не обновлена ​​до C ++ 20 и поэтому принимает и возвращает строки UTF-8 как обычные {{X2} } s вместо std::u8string s.

Преобразование std::u8string в std::string довольно просто, поскольку к буферу u8string можно получить доступ через указатель char*, поэтому

std::u8string u8s = get_data();
std::string s(reinterpret_cast<char const*>(u8s.data()), u8s.size());

Правильный код. Однако, насколько мне известно, char8_t не имеет исключения псевдонимов, которое есть у std::byte и char, поэтому

std::string s = get_data();
std::u8string u8s{reinterpret_cast<char8_t const*>(s.data()), s.size());

Не является допустимым.

Я прибегал к

std::string s = get_data();
std::u8string u8s(s.size(), u8'\0');
std::memcpy(u8s.data(), s.data(), s.size());

На данный момент, но это кажется излишне неэффективным, учитывая, что это сначала инициализирует память всеми нулями перед записью в нее фактических данных.

Есть ли способ избежать инициализации всеми нулями или другой способ полностью преобразовать std::string в std::u8string?

0
Corristo 24 Сен 2020 в 17:42

1 ответ

Лучший ответ

u8string u8s(s.begin(), s.end()) должно работать нормально. Вам не нужен гипс. Конструктор является шаблоном, и char неявно преобразуется в char8_t.

Базовый тип char8_t, являющийся unsigned char, не является проблемой, даже если char является типом со знаком.

1
eerorika 24 Сен 2020 в 14:58