Dans la référence CPP documentation ,
J'ai remarqué pour char
Les types de caractères sont suffisamment grands pour représenter n'importe quelle unité de code huit bits UTF-8 (depuis C++ 14)
et pour char8_t
type pour la représentation des caractères UTF-8, doit être suffisamment grand pour représenter n'importe quelle unité de code UTF-8 (8 bits)
Est-ce à dire que les deux sont du même type? Ou est-ce que char8_t
avez une autre fonctionnalité?
char8_t
n'est pas identique à char
. Il se comporte exactement comme unsigned char
bien que par [basic.fundamental]/9
Tapez
char8_t
désigne un type distinct dont le type sous-jacent estunsigned char
. Les typeschar16_t
etchar32_t
désigne des types distincts dont les types sous-jacents sontuint_least16_t
etuint_least32_t
, respectivement, dans<cstdint>.
mettre l'accent
Notez que puisque la norme l'appelle un type distinct, un code comme
std::cout << std::is_same_v<unsigned char, char8_t>;
imprimera 0
(faux), même si char8_t
est implémenté en tant que unsigned char
. C'est parce que ce n'est pas un alias, mais un type distinct.
Une autre chose à noter est que char
peut être implémenté en tant que signed char
ou unsigned char
. Cela signifie qu'il est possible que char
ait la même plage et la même représentation que char8_t
, mais ce sont toujours des types distincts. char
, signed char
, unsigned char
, et char8_t
ont la même taille, mais ce sont tous des types distincts.
Avertissement: je suis l'auteur du char8_t
P0482 et P142 propositions.
En C++ 20, char8_t
est un type distinct de tous les autres types. Dans la proposition connexe pour C, N2231 (qui a besoin d'une mise à jour et d'une nouvelle proposition au WG14), char8_t
serait un typedef de unsigned char
similaire aux typedefs existants pour char16_t
et char32_t
.
En C++ 20, char8_t
a une représentation sous-jacente qui correspond à unsigned char
. Il a donc la même taille (au moins 8 bits, mais peut être plus grande), l'alignement et le rang de conversion entier que unsigned char
, mais avec des règles d'alias différentes.
En particulier, char8_t
n'a pas été ajouté à la liste des types à [basic.lval] p11 . [basic.life] p6.4 , [basic.types] p2 , ou [basic.types] p4 . Cela signifie que, contrairement à unsigned char
, il ne peut pas être utilisé pour le stockage sous-jacent d'objets d'un autre type, ni pour examiner la représentation sous-jacente d'objets d'autres types; en d'autres termes, il ne peut pas être utilisé pour alias d'autres types. Une conséquence de cela est que les objets de type char8_t
est accessible via des pointeurs vers char
ou unsigned char
, mais pointe vers char8_t
ne peut pas être utilisé pour accéder à char
ou unsigned char
Les données. En d'autres termes:
reinterpret_cast<const char *>(u8"text"); // Ok.
reinterpret_cast<const char8_t*>("text"); // Undefined behavior.
La motivation pour un type distinct avec ces propriétés est:
Pour fournir un type distinct pour les données de caractères UTF-8 par rapport aux données de caractères avec un codage dépendant des paramètres régionaux ou nécessitant des spécifications distinctes.
Pour activer la surcharge pour les littéraux de chaîne ordinaires par rapport aux littéraux de chaîne UTF-8 (car ils peuvent avoir des encodages différents).
Pour garantir un type non signé pour les données UTF-8 (que char
soit signé ou non signé est défini par l'implémentation).
Pour permettre de meilleures performances via un type sans alias; les optimiseurs peuvent mieux optimiser les types qui ne sont pas des alias d'autres types.