web-dev-qa-db-fra.com

C ++ 20 avec u8, char8_t et std :: string

C++ 11 nous a apporté le préfixe u8 pour les littéraux UTF-8 et je pensais que c'était assez cool il y a quelques années et j'ai parsemé mon code de choses comme ceci:

std::string myString = u8"●";

Tout va bien, mais le problème survient en C++ 20, il ne semble plus se compiler car u8 crée un char8_t * et cela est incompatible avec std :: string qui utilise simplement char.

Dois-je créer une nouvelle chaîne utf8? Quelle est la manière cohérente et correcte de faire ce genre de chose dans un monde C++ 20 où nous avons des types plus explicites qui ne correspondent pas vraiment à la chaîne std :: string standard?

26
M2tM

En plus de la réponse de @ lubgr, l'article correction de la compatibilité descendante char8_t (P1423) décrit plusieurs façons de faire std::string avec char8_t tableaux de caractères.

Fondamentalement, l'idée est que vous pouvez lancer le u8 tableau de caractères dans un tableau de caractères "normal" pour obtenir le même comportement que C++ 17 et avant, il suffit d'être un peu plus explicite. Le papier discute de diverses manières de faire ceci.

La méthode la plus simple (mais pas entièrement nulle, sauf si vous ajoutez plus de surcharges) qui correspond à votre cas d'utilisation est probablement la dernière, c'est-à-dire introduire des fonctions de conversion explicites:

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
15
Fabio Fracassi

Dois-je créer une nouvelle chaîne utf8?

Non, c'est déjà là. P0482 ne propose pas seulement char8_t, mais aussi une nouvelle spécialisation de std::basic_string pour char8_t types de caractères nommés std::u8string. Donc, cela compile déjà avec clang et libc++ du coffre:

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

Le fait que std::string construction à partir d'un u8- les ruptures littérales sont regrettables. De la proposition:

Cette proposition ne spécifie aucune fonctionnalité de compatibilité descendante autre que de conserver les interfaces qu'elle déconseille. L'auteur estime que de telles fonctionnalités sont nécessaires, mais qu'un ensemble unique de telles fonctionnalités compromettrait inutilement les objectifs de cette proposition. On s'attend plutôt à ce que les implémentations fournissent des options permettant d'activer des fonctionnalités de compatibilité plus fines.

Mais je suppose que la plupart des initialisations comme ci-dessus devraient être grep- capables ou être soumises à quelques correctifs automatiques clang.

14
lubgr