c++ stdstring c++20

C++ 20 con u8, char8_t y std:: string



stdstring c++20 (2)

C ++ 11 nos trajo el prefijo u8 para los literales UTF-8 y pensé que era muy bueno hace unos años y salpicé mi código con cosas como esta:

std::string myString = u8"●";

Todo esto está muy bien, pero el problema aparece en C ++ 20, parece que ya no se compila porque u8 crea un char8_t * y esto es incompatible con std :: string que solo usa char.

¿Debo estar creando una nueva utf8string? ¿Cuál es la manera correcta y coherente de hacer este tipo de cosas en un mundo de C ++ 20 donde tenemos tipos más explícitos que no coinciden realmente con la cadena estándar std ::?


¿Debo estar creando una nueva utf8string?

No, ya está ahí. P0482 no solo propone char8_t , sino también una nueva especialización de std::basic_string para los tipos de caracteres char8_t denominados std::u8string . Así que esto ya compila con clang y libc++ desde el tronco:

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

El hecho de que la construcción de std::string de u8 -literal se rompa es desafortunado. De la propuesta:

Esta propuesta no especifica ninguna característica de compatibilidad con versiones anteriores que no sea la de retener las interfaces que deja en desuso. La falta de tales características no se debe a la creencia de que las características de compatibilidad con versiones anteriores no son necesarias. El autor cree que tales características son necesarias, pero las limitaciones de tiempo impidieron investigar adecuadamente qué problemas deben abordarse, en qué medida deben abordarse y cómo deben especificarse esas características. [...]

Pero supongo que la mayor parte de la inicialización como la anterior debería ser grep -able o estar sujeta a algunas correcciones de herramientas de sonido automático.


Además de la respuesta de @lubgr, la corrección de compatibilidad con versiones anteriores del artículo char8_t (P1423) describe varias formas de hacer std::string con matrices de caracteres char8_t .

Básicamente, la idea es que puede convertir la matriz de caracteres u8 en una matriz de caracteres "normal" para obtener el mismo comportamiento que C ++ 17 y antes, solo tiene que ser un poco más explícito. El documento discute varias maneras de hacer esto.

El método más simple (pero no totalmente nulo, a menos que agregue más sobrecargas) que se ajuste a su caso de uso es probablemente el último, es decir, introduzca funciones de conversión explícitas:

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