C ++ 20的“ char8_t”与我们以前的“ char”相同吗?

时间:2019-08-07 21:23:20

标签: c++ c++14 c++20

在CPP参考documentation中,

我注意到CASE WHEN `Item Amount(s)` < 0 THEN 3 WHEN `Item Amount(s)` NULL THEN 2 ELSE 1 END ASC

  

字符类型足够大,可以表示任何UTF-8八位   代码单元(自C ++ 14起)

char

  UTF-8字符表示形式的

类型,必须足够大   代表任何UTF-8代码单元(8位)

这是否意味着两种类型相同?还是char8_t还有其他功能?

2 个答案:

答案 0 :(得分:41)

char8_tchar不同。尽管每个[basic.fundamental]/9的行为与unsigned char完全相同

  

类型char8_­t表示其基础类型为unsigned char 的不同类型。类型char16_­tchar32_­t表示在uint_­least16_­t

中其基础类型分别为uint_­least32_­t<cstdint>.的不同类型。

强调我的


请注意,由于该标准将其称为不同类型,因此代码类似

std::cout << std::is_same_v<unsigned char, char8_t>;
即使0被实现为char8_t

也会打印unsigned char(假)。这是因为它不是别名,而是不同的类型。


要注意的另一件事是,char可以实现为signed charunsigned char。这意味着char可以具有与char8_t相同的范围和表示形式,但是它们仍然是单独的类型。 charsigned charunsigned charchar8_t的大小相同,但都是不同的类型。

答案 1 :(得分:19)

免责声明:我是char8_t P0482P1423提案的作者。

在C ++ 20中,char8_t是与所有其他类型不同的类型。在C的相关提案N2231(需要对WG14进行更新和重新提议)中,char8_t将是unsigned char的typedef,类似于{ {1}}和char16_t

在C ++ 20中,char32_t具有与char8_t匹配的基础表示形式。因此,它具有与unsigned char相同的大小(至少8位,但可能更大),对齐方式和整数转换等级,但是具有不同的别名规则。

尤其是,unsigned char没有添加到[basic.lval]p11的类型列表中。 [basic.life]p6.4[basic.types]p2[basic.types]p4。这意味着,与char8_t不同,它不能用于其他类型的对象的基础存储,也不能用于检查其他类型的对象的基础表示;换句话说,它不能用于别名其他类型。这样的结果是可以通过指向unsigned charchar8_t的指针来访问类型char的对象,但是不能使用指向unsigned char的指针来访问char8_tchar数据。换句话说:

unsigned char

具有这些属性的独特类型的动机是:

  1. 要为UTF-8字符数据和字符数据提供不同的类型,其编码要么取决于语言环境,要么需要单独的规范。

  2. 为普通字符串文字和UTF-8字符串文字启用重载(因为它们可能具有不同的编码)。

  3. 要确保UTF-8数据的无符号类型(reinterpret_cast<const char *>(u8"text"); // Ok. reinterpret_cast<const char8_t*>("text"); // Undefined behavior. 是有符号的还是无符号的,是实现的定义。)

  4. 通过非混叠类型实现更好的性能;优化器可以更好地优化不别名其他类型的类型。