据我了解,achar
可以安全地容纳 ASCII 字符,而char16_t
可以char32_t
安全地容纳来自 unicode 的字符,一个用于 16 位变体,另一个用于 32 位变体(我应该说“a”而不是“the”吗? ?)。但是我想知道背后的目的wchar_t
是什么。我应该在新代码中使用该类型,还是只是为了支持旧代码?wchar_t
如果据我了解,如果它的大小不能保证大于 a ,那么旧代码的目的是什么char
?澄清会很好!
2 回答
char
用于 8 位代码单元、char16_t
用于 16 位代码单元和char32_t
用于 32 位代码单元。这些中的任何一个都可以用于“Unicode”;UTF-8 使用 8 位代码单元,UTF-16 使用 16 位代码单元,UTF-32 使用 32 位代码单元。
做出的保证wchar_t
是语言环境中支持的任何字符都可以从 转换char
为wchar_t
,以及用于 的任何表示形式,无论是char
多字节、移位代码、你有什么,都wchar_t
将是一个单一的、不同的值。这样做的目的是,您可以wchar_t
像使用 ASCII 的简单算法一样操作字符串。
例如,将 ascii 转换为大写如下:
auto loc = std::locale("");
char s[] = "hello";
for (char &c : s) {
c = toupper(c, loc);
}
但这不会处理将 UTF-8 中的所有字符转换为大写字母,或者将所有其他编码(如 Shift-JIS)中的所有字符。人们希望能够像这样国际化这段代码:
auto loc = std::locale("");
wchar_t s[] = L"hello";
for (wchar_t &c : s) {
c = toupper(c, loc);
}
所以每个wchar_t
都是一个“字符”,如果它有一个大写版本,那么它可以直接转换。不幸的是,这并不是一直都有效。例如,在某些语言中存在奇怪之处,例如德语字母 ß,其中大写版本实际上是两个字符 SS 而不是单个字符。
因此,国际化文本处理本质上比 ASCII 更难,并且不能真正按照设计者wchar_t
预期的方式进行简化。因此wchar_t
,宽字符通常提供的价值很小。
使用它们的唯一原因是它们已经融入了一些 API 和平台。但是,即使在这样的平台上开发,我也更喜欢在自己的代码中坚持使用 UTF-8,并且只是在 API 边界处转换为所需的任何编码。
当 Unicode 承诺创建 16 位表示时,该类型wchar_t
被纳入标准。大多数供应商选择制造wchar_t
32 位,但一家大型供应商选择制造 16 位。由于 Unicode 使用超过 16 位(例如,20 位),我们认为我们应该有更好的字符类型。
for 的目的char16_t
是表示 UTF16,并char32_t
旨在直接表示 Unicode 字符。但是,在使用wchar_t
作为其基本接口的一部分的系统上,您将被wchar_t
. 如果您不受约束,我会亲自使用char
UTF8 来表示 Unicode。char16_t
and的问题char32_t
是它们没有得到完全支持,甚至在标准 C++ 库中也不支持:例如,没有直接支持这些类型的流,它比仅仅为这些类型实例化流更有效。